# Gentoo Linux Bash Shell Command Completion # # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License, v2 or later # Retrieve PORTDIR/PORTDIR_OVERLAY location. # # In order of highest to lowest priority: # /etc/portage/repos.conf{,/*} # /usr/share/portage/config/repos.conf # /etc/portage/make.conf # /etc/make.conf # /usr/share/portage/config/make.globals # # The first two files are in repos.conf format and must be parsed for the # variable "location". The rest are make.conf style and are simply sourced # for PORTDIR and PORTDIR_OVERLAY. While repos.conf overrides any value of # PORTDIR set in make.conf, PORTDIR_OVERLAY is incremental (combined across # available sources). # # This would be a hell of a lot simpler if we used portageq, but also about # 500 times slower. _portdir() { local mainreponame mainrepopath overlayname overlaypath if [[ -e @GENTOO_PORTAGE_EPREFIX@/usr/share/portage/config/repos.conf ]]; then if [[ ${1} == -o ]]; then for overlayname in $(_parsereposconf -l); do overlaypath+=($(_parsereposconf ${overlayname} location)) done source @GENTOO_PORTAGE_EPREFIX@/etc/make.conf 2>/dev/null source @GENTOO_PORTAGE_EPREFIX@/etc/portage/make.conf 2>/dev/null overlaypath+=(${PORTDIR_OVERLAY}) # strip out duplicates overlaypath=($(printf "%s\n" "${overlaypath[@]}" | sort -u)) echo "${overlaypath[@]}" else mainreponame=$(_parsereposconf DEFAULT main-repo) mainrepopath=$(_parsereposconf ${mainreponame} location) echo "${mainrepopath}" fi else source @GENTOO_PORTAGE_EPREFIX@/usr/share/portage/config/make.globals 2>/dev/null source @GENTOO_PORTAGE_EPREFIX@/etc/make.conf 2>/dev/null source @GENTOO_PORTAGE_EPREFIX@/etc/portage/make.conf 2>/dev/null echo "${PORTDIR}" if [[ ${1} == -o ]]; then echo "${PORTDIR_OVERLAY}" fi fi } # _parsereposconf [-l] # -l lists available repos _parsereposconf() { local f insection line section v value var for f in @GENTOO_PORTAGE_EPREFIX@/usr/share/portage/config/repos.conf \ @GENTOO_PORTAGE_EPREFIX@/etc/portage/repos.conf \ @GENTOO_PORTAGE_EPREFIX@/etc/portage/repos.conf/*.conf; do [[ -f ${f} ]] || continue insection=0 while read -r line; do # skip comments and blank lines [[ -z ${line} || ${line} == '#'* ]] && continue if [[ ${insection} == 1 && ${line} == '['*']' ]]; then # End of the section we were interested in so stop secname+=(${line//[(\[|\])]/}) # record name for -l break elif [[ ${line} == '['*']' ]]; then # Entering a new section, check if it's the one we want section=${line//[(\[|\])]/} [[ ${section} == "${1}" ]] && insection=1 secname+=(${section}) # record name for -l elif [[ ${insection} == 1 ]]; then # We're in the section we want, grab the values var=${line%%=*} var=${var// /} value=${line#*=} value=${value# } [[ ${var} == ${2} ]] && v=${value} fi continue done < "${f}" done if [[ ${1} == -l ]]; then echo "${secname[@]}" else echo "${v}" fi } # like _pkgname but completes on package names only (no category) _pkgname_only() { local i pd local cur="$1" shift local dir="$@" COMPREPLY=($(compgen -W "$(\ for pd in $dir ; do \ builtin cd ${pd}; \ for i in *-*/${cur}*; do \ [[ -d ${i} ]] && { local x=${i##*/} ; echo ${x%-[0-9]*}; } \ done ; \ done)" -- ${cur})) } # # This function completes package names. # # usage: pkgname # # Where mode is one of: # -A Search all available packages (except for those in the overlays) # -I Only search the installed packages # # TODO: Look at breaking this function out and making it a "universal" # category/package name completion function. # _pkgname() { local mode cur portdir only mode="$1" cur="$2" portdir=$(_portdir -o) # Ignore '=' at the beginning of the current completion [[ ${cur:1:1} == "=" ]] && cur=${cur:2} [[ ${cur:0:1} == "=" ]] && cur=${cur:1} case $mode in -I) # Complete either the category or the complete package name if [[ $cur == */* ]]; then COMPREPLY=($(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg; compgen -W "$(compgen -G "$cur*" )" -- $cur)) else COMPREPLY=($(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg; compgen -W "$(compgen -G "$cur*" -S /)" -- $cur)) fi # We may just have finished completing the category. # Make sure there isn't anything more to complete now. if [[ ${#COMPREPLY[@]} == 1 ]]; then COMPREPLY=($(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg; compgen -W "$(compgen -G "$COMPREPLY*")" -- $cur)) fi if [[ -z "${COMPREPLY}" ]] ; then only=1 _pkgname_only ${cur} @GENTOO_PORTAGE_EPREFIX@/var/db/pkg fi ;; -A) # Complete either the category or the complete package name if [[ $cur == */* ]]; then # Once the category has been completed, it's safe to use ${portdir} # to continue completion. local ww=$(\ for pd in ${portdir} ; do builtin cd ${pd}; compgen -W "$(compgen -G "${cur}*")" -- "${cur}" ; done) COMPREPLY=($(\ for x in ${ww}; do echo $x; done|sort -u )) # When we've completed most of the name, also display the version for # possible completion. if [[ ${#COMPREPLY[@]} -le 1 || ${cur:${#cur}-1:1} == "-" ]] \ && [[ ${cur} != */ ]]; then # Use the portage cache to complete specific versions from COMPREPLY=(${COMPREPLY[@]} $( for pd in ${portdir}; do if [[ -d ${pd}/metadata/md5-cache ]]; then builtin cd ${pd}/metadata/md5-cache compgen -W "$(compgen -G "${cur}*")" -- "${cur}" elif [[ -d ${pd}/metadata/cache ]]; then builtin cd ${pd}/metadata/cache compgen -W "$(compgen -G "${cur}*")" -- "${cur}" fi done )) fi else # 1. Collect all the categories among ${portdir} local ww=$(\ for pd in ${portdir}; do builtin cd ${pd}; compgen -X "!@(*-*|virtual)" -S '/' -G "$cur*"; done) # 2. Now ugly hack to delete duplicate categories local w x for x in ${ww} ; do w="${x}\n${w}"; done local words=$(echo -e ${w} | sort -u) COMPREPLY=($(compgen -W "$words" -- $cur)) if [[ ${#COMPREPLY[@]} == 1 ]]; then COMPREPLY=($(compgen -W "$( for pd in ${portdir}; do if [[ -d ${pd}/metadata/md5-cache ]]; then builtin cd ${pd}/metadata/md5-cache compgen -G "$COMPREPLY*" elif [[ -d ${pd}/metadata/cache ]]; then builtin cd ${pd}/metadata/cache compgen -G "$COMPREPLY*" fi done )" -- $cur)) fi fi if [[ -z "${COMPREPLY}" ]] ; then only=1 _pkgname_only ${cur} ${portdir} fi ;; *) # Somebody screwed up! :-) ;; esac # 'equery' wants an '=' in front of specific package versions. # Add it if there is only one selected package and it isn't there already. if [[ ${#COMPREPLY[@]} == 1 && ${COMP_WORDS[COMP_CWORD]:0:1} != "=" ]] then [[ -z "${only}" ]] && COMPREPLY=("="$COMPREPLY) fi } # # This is an helper function for completion of "-o " / "--option=" # kind of command lines options. # # Usage: _list_compgen [ ...] # - : what we have so far on the command line # - : the separator character used in lists # - : a valid item # Returns: the function outputs each possible completion (one per line), # and returns 0. Typical usage is COMPREPLY=($(_list_compgen ...)). # # Note: items must not contain the character (no backslash escaping has # been implemented). # _list_compgen() { # Read the three parameters. local current="${1}" ; shift local sep="${1}" ; shift local items="${*}" # This is the maximum number of "" possible # completions that should be listed in case is a valid list. # Setting it to a negative value means "no bound" (always list everything). # Setting it to 0 means "never list anything" (only suggest ). # Setting it to a positive value N means "list up to N possible items, and # only suggest if there are more". # It is probably not worth a parameter, thus it will defaults to my # prefered setting (1) if not already defined in the environment. local max_others_number=${max_others_number:-1} # Save IFS. The character will be used instead in the following. local saved_IFS="${IFS}" IFS="${sep}" # Split the current items list in two parts: # - current_item is the last one (maybe partial or even empty) # - prefix_item are items are the previous ones local current_item="${current##*${sep}}" local prefix_items="${current%${current_item}}" # Iterate through valid items to recognize those that are: # - partial matches of the # - already used in the list prefix # - not used in the list prefix, and not an exact match of # Also check whether the is exactly a valid one. local matching_items local other_items local exact_match local my_item for my_item in ${items} ; do if [[ "${sep}${prefix_items}${sep}" == *"${sep}${my_item}${sep}"* ]] ; then # The item has already been used in the list prefix: ignore it. continue elif [[ "${my_item}" == "${current_item}" ]] ; then # The item _exactly_ matches the : that means that we # will have to suggest some more items to add behind. exact_match=1 elif [[ "${my_item}" == "${current_item}"* ]] ; then # The item matches the : it will be a possible # completion. It will also be a possible additional item in case of # exact match. matching_items="${matching_items}${sep}${my_item}" other_items="${other_items}${sep}${my_item}" else # The item neither matches the nor has been already # used: it will only be a possible additional item in case of exact # match. other_items="${other_items}${sep}${my_item}" fi done matching_items="${matching_items#${sep}}" other_items="${other_items#${sep}}" # Takes care of the case where is not exactly valid but # there is only one matching item: force this completion, and handle it # just as an exact match. if [[ -z "${exact_match}" ]] \ && [[ "${matching_items}" != *"${sep}"* ]] ; then exact_match=1 current="${current%${current_item}}${matching_items}" current_item="${matching_items}" matching_items="" other_items="${sep}${other_items}${sep}" other_items="${other_items/${sep}${current_item}${sep}/${sep}}" other_items="${other_items#${sep}}" other_items="${other_items%${sep}}" fi # List all possible completions. They are stored in an array. # XXX: maybe if should be COMPREPLY directly? (with no output at the end) local my_compreply=() local i=0 if [[ -n "${exact_match}" ]] ; then # Found an exact match? Then add "". my_compreply[${i}]="${current}" let i++ fi if [[ -n "${matching_items}" ]] ; then # Found some matching items? # Then add "". for my_item in ${matching_items} ; do my_compreply[${i}]="${prefix_items}${my_item}" let i++ done fi if [[ -n "${exact_match}" ]] \ && [[ -n "${other_items}" ]] ; then # Found an exact match and some other possible items remain? # First, count them: local count_others=0 for my_item in ${other_items} ; do let count_others++ done # Then decide how to behave depending on the max_others_number setting: if (( max_others_number < 0 )) \ || (( count_others <= max_others_number )) ; then # List the possible "" completions. for my_item in ${other_items} ; do my_compreply[${i}]="${current}${sep}${my_item}" let i++ done else # Only suggest adding the character. my_compreply[${i}]="${current}${sep}" let i++ fi fi # Restore IFS. IFS="${saved_IFS}" # Output the array of possible completions and returns. local j=0 while (( i > j )) ; do echo ${my_compreply[$j]} let j++ done return 0 } # # emerge completion command # _emerge() { local c cur prev curword numwords opts cond prepend local words stophere i x local action actionpos sysactions pkgpos local portdir=$(_portdir -o) COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" numwords=${#COMP_WORDS[*]} curword=${COMP_CWORD} opts='' if [[ ${prev} == '>' || ${prev} == '<' ]] ; then COMPREPLY=($(compgen -f -- ${cur})) return 0 fi # find action for x in ${COMP_LINE} ; do if [[ ${x} =~ ^(system|world)$ ]] || [[ ${x} =~ -[CPcs] ]] || \ [[ ${x} =~ --(clean|config|depclean|info|metadata|prune|regen|resume|search|sync|unmerge) ]] then action=${x} break fi done if [[ -n ${action} ]]; then for ((i = 0; i < ${numwords}; i++ )); do if [[ ${COMP_WORDS[${i}]} == "${action}" ]]; then actionpos=${i} pkgpos=$((actionpos + 1)) break fi done if [[ ${action} == -* && ${action} != --* ]] ; then case "${action}" in -*C*) action='--unmerge' ;; -*P*) action='--prune' ;; -*c*) action='--clean' ;; -*s*) action='--search' ;; esac fi else for ((i = 1; i < ${numwords}; i++ )); do if [[ ! ${COMP_WORDS[$i]} == -* ]]; then pkgpos=${i} break fi done [[ -z ${pkgpos} ]] && pkgpos=${numwords} fi # Handle special cases. if [[ ${action} == "--search" ]] || [[ ${COMP_LINE} == *" "-@(S|-searchdesc)* ]] || \ [[ ${COMP_LINE} == *" "-@(V|-version)* ]] || [[ ${action} == "--metadata" ]] then unset COMPREPLY return 0 elif [[ ${COMP_LINE} == *" "-@(h|-help)* ]] ; then unset COMPREPLY [[ ${curword} -eq 2 ]] && COMPREPLY=($(compgen -W 'system world --sync' -- ${cur})) return 0 fi # Complete on options. if [[ ${cur} == -* ]]; then # If a resume option was specified, it needs special handling. if [[ ${COMP_LINE} =~ --(resume|skipfirst) ]] ; then if [[ ${cur} == --* ]]; then opts="--ask --pretend --resume --skipfirst" elif [[ ${cur} == -* ]]; then [[ ${COMP_LINE} =~ --(ask|pretend) ]] && opts="-a -p" fi elif [[ ${cur} == --* ]]; then # Complete on long options. opts="--alphabetical --ask \ --buildpkg --buildpkgonly \ --changelog --clean --color=y --color=n --columns --complete-graph --config \ --debug --deep --depclean \ --emptytree \ --fetch-all-uri --fetchonly \ --getbinpkg --getbinpkgonly \ --ignore-default-opts --info \ --jobs= \ --keep-going \ --metadata \ --newuse --noconfmem --nodeps --noreplace --nospinner \ --oneshot --onlydeps \ --pretend --prune \ --quiet \ --reinstall=changed-use --regen \ --search \ --sync \ --tree \ --unmerge --update --upgradeonly --usepkg --usepkgonly \ --verbose \ --with-bdeps=y --with-bdeps=n" if [[ ${curword} -eq 1 ]] && [[ ${numwords} -eq 2 ]] ; then opts="${opts} --help --resume --searchdesc --version" fi elif [[ ${cur} == -* ]]; then # Complete on short options. opts="-B -D -G -K -N -O -a -b -d -e -f -g -k -l -n -o -p -q -t -u -v" if [[ ${curword} -eq 1 ]] && [[ ${numwords} -eq 2 ]] ; then opts="${opts} -h -S -V" fi if [[ -z ${action} ]] && [[ ${curword} -eq $((pkgpos - 1)) ]] ; then opts="${opts} -C -P -c -s" fi fi COMPREPLY=($(compgen -W "${opts}" -- ${cur})) # NOTE: This slows things down! # (Adapted from bash_completion by Ian Macdonald ) # This removes any options from the list of completions that have # already been specified on the command line. COMPREPLY=($(echo "${COMP_WORDS[@]}" | \ (while read -d ' ' i; do [[ -z ${i} ]] && continue # flatten array with spaces on either side, # otherwise we cannot grep on word boundaries of # first and last word COMPREPLY=" ${COMPREPLY[@]} " # remove word from list of completions COMPREPLY=(${COMPREPLY/ ${i%% *} / }) done echo ${COMPREPLY[@]}))) return 0 fi # options # Stop completion if a special case is encountered. if [[ ${action} =~ (system|world) ]] || \ [[ ${COMP_LINE} =~ --(depclean|metadata|regen|resume|skipfirst|sync) ]] then unset COMPREPLY return 0 fi # Complete on installed packages when unmerging. if [[ "${action}" == '--unmerge' ]]; then if [[ -n "${cur}" ]] ; then if [[ "${cur}" == */* ]]; then words=$(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg; compgen -G "${cur}*") else words=$(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg; compgen -S '/' -G "${cur}*") local n=0 for i in ${words} ; do [[ ${i} == ${cur}* ]] && n=$((n+1)) done if [[ ${n} -eq 1 ]] ; then words="$(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg ; compgen -G "*-*/*")" fi fi COMPREPLY=($(for i in ${words} ; do \ [[ ${i} == ${cur}* ]] && echo ${i} ; \ done)) else COMPREPLY=($(builtin cd @GENTOO_PORTAGE_EPREFIX@/var/db/pkg ; compgen -S '/' -G "*-*")) fi [[ -z "${COMPREPLY}" ]] && _pkgname_only ${cur} @GENTOO_PORTAGE_EPREFIX@/var/db/pkg return 0 fi # Check for conditional. cond="${cur%%[A-Za-z0-9]*}" cur="${cur:${#cond}}" if [[ ${cond:0:1} == "'" || ${cond:0:1} == '"' ]] ; then prepend="-P ${cond:1}" c="${cond:1}" else c="${cond}" fi # Handle cases where a conditional is specified. if [[ -n "${cond}" ]]; then if [[ -n "${cur}" ]]; then if [[ ${cur} == */* ]]; then if [[ ${cur} == *-[0-9]* ]] ; then words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd} ; \ local cat="${cur%/*}" ; \ local pkg="$(echo ${cur%-[0-9]*})" ; \ pkg="${pkg##*/}" ; \ for x in ${cat}/${pkg}/*.ebuild ; do \ [[ -f ${x} ]] || continue ; \ x="${x/${pkg}\/}" ; \ echo "${x%*.ebuild}" ; \ done ; \ done)" else words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd}; \ compgen -X "*metadata.xml" -G "${cur}*" -- ${cur} ; \ done)" fi local w for x in $words ; do w="${x}\n${w}" done words=$(echo -ne ${w} | sort | uniq) COMPREPLY=( ${words} ) # Complete on the specific versions (if appropriate). # TODO - see if we can use _pkgname if [[ ${#COMPREPLY[@]} -le 1 ]]; then COMPREPLY=($( for pd in ${portdir}; do if [[ -d ${pd}/metadata/md5-cache ]]; then builtin cd ${pd}/metadata/md5-cache compgen ${prepend} -G "${cur}*" -- "${cur}" elif [[ -d ${pd}/metadata/cache ]]; then builtin cd ${pd}/metadata/cache compgen ${prepend} -G "${cur}*" -- "${cur}" else builtin cd ${pd} local cat="${cur%/*}" local pkg="$(echo ${cur%-[0-9]*}*)" pkg="${pkg##*/}" for x in ${cat}/${pkg}/*.ebuild; do [[ -f "${x}" ]] || continue x="${x/${pkg}\/}" if [[ ${cond:0:1} == "'" ]] || [[ ${cond:0:1} == '"' ]]; then echo "${c}${x%*.ebuild}" else echo "${x%*.ebuild}" fi done fi done )) else COMPREPLY=($(compgen ${prepend} -W "${words}" -- $cur)) fi else words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd} ; \ compgen ${prepend} -S '/' -G "${cur}*" -- "${cur}" ; \ done)" local w for x in words ; do w="${x}\n${w}" done COMPREPLY=($(echo -e ${w} | uniq)) [[ ${#COMPREPLY[@]} = 1 ]] && \ COMPREPLY=($(\ for pd in ${portdir} ; do \ builtin cd ${pd} ; \ compgen ${prepend} -G "${cur}*/*" -- "${cur}" ; \ done)) fi else words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd}; \ compgen -G "*-*"; \ done)" COMPREPLY=($(compgen -W "${words}" -- "${cur}")) fi # If all else fails, try to complete on package names without the # category being specified. if [[ -z "${COMPREPLY}" ]]; then words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd}; \ for i in *-*/${cur}*; do \ [[ -d $i ]] && echo ${i##*/}; \ done ; \ done)" COMPREPLY=($(compgen ${prepend} -W "${words}" -- ${cur})) if [[ ${#COMPREPLY[@]} -le 1 ]]; then # Now complete on the specific versions. words="$( for pd in ${portdir}; do if [[ -d ${pd}/metadata/md5-cache ]]; then builtin cd ${pd}/metadata/md5-cache for i in */${cur}*; do [[ -f $i ]] && echo ${i##*/} done elif [[ -d ${pd}/metadata/cache ]]; then builtin cd ${pd}/metadata/cache for i in */${cur}*; do [[ -f $i ]] && echo ${i##*/} done fi done )" COMPREPLY=($(compgen ${prepend} -W "${words}" -- "${cur}")) fi fi return 0 fi # Complete on packages. # # Only allow these actions if no packages have been specified. # # TODO: This doesn't block these actions if no categories are # specified. Please fix me. # # e.g. emerge -a gentoo-dev-sources # # will still allow system and world actions to be specified, # as opposed to # # emerge -a sys-kernel/gentoo-dev-sources # if [[ ${COMP_CWORD} -eq 1 ]] || [[ ! " ${COMP_LINE} " == *" "*[/]*" "* ]] ; then sysactions=$'\n'"system"$'\n'"world" else sysactions='' fi if [[ -n "${cur}" ]] ; then if [[ ${cur} == */* ]] ; then words=$(\ for pd in ${portdir} ; do \ builtin cd ${pd}; \ compgen -X "*metadata.xml" -G "${cur}*" ; \ done)"${sysactions}" else local ww=$(\ for pd in ${portdir} ; do \ builtin cd ${pd} ; \ compgen -X "!@(*-*|virtual)" -S '/' -G "${cur}*"; \ done)"${sysactions}" # complete on virtuals ww="${ww} $(\ for pd in ${portdir} ; do \ if [[ -d ${pd}/profiles ]] ; then find ${pd}/profiles -name virtuals -exec \ sed -n -e 's|^\(virtual/[[:alnum:]]\+\).*$|\1|p' {} \; | \ sort -u fi ; \ done)" local w for x in ${ww} ; do w="${x}\n${w}" ; done words=$(echo -e ${w} | sort -u) local n=0 for i in ${words} ; do [[ ${i} == ${cur}* ]] && n=$((n+1)) done if [[ ${n} -eq 1 ]] ; then words=$(for pd in ${portdir} ; do \ builtin cd ${pd} ; \ compgen -G "*-*/*" ; \ done)"${sysactions}" fi fi COMPREPLY=($(for i in ${words} ; do \ [[ ${i} == ${cur}* ]] && echo ${i} ; \ done)) else words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd} ; \ compgen -S '/' -G "*-*" ; \ done)""${sysactions}" COMPREPLY=($(compgen -W "${words}" -- ${cur})) fi # If all else fails, try to complete on package names without the # category being specified. if [[ -z "${COMPREPLY}" ]]; then words="$(\ for pd in ${portdir} ; do \ builtin cd ${pd}; \ for i in [a-z]*-[a-z0-9]*/${cur}*; do \ [[ -d $i ]] && echo ${i##*/}; \ done ; \ done)" COMPREPLY=($(compgen -W "${words}" -- ${cur})) fi return 0 } && complete -o filenames -F _emerge emerge # # ebuild completion command # _ebuild() { local cur opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" opts="help setup clean fetch digest manifest unpack compile test preinst \ install postinst qmerge merge unmerge prerm postrm config package rpm \ configure prepare" if [[ $COMP_CWORD -eq 1 ]] ; then COMPREPLY=($(compgen -f -X "!*.ebuild" -- ${cur}) \ $(compgen -d -- ${cur}) \ $(compgen -W '--debug --force --help --ignore-default-opts --skip-manifest' -- ${cur})) elif [[ $COMP_CWORD -eq 2 && "${COMP_WORDS[1]}" = "--debug --force --ignore-default-opts --skip-manifest" ]] ; then COMPREPLY=($(compgen -f -X "!*.ebuild" -- ${cur}) $(compgen -d -- ${cur})) elif [[ $COMP_CWORD -ge 2 ]] ; then COMPREPLY=($(compgen -W "${opts}" -- ${cur})) fi return 0 } && complete -o filenames -F _ebuild ebuild # # rc completion command # _rc() { local cur COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" if [[ ${#COMP_WORDS[*]} -le 2 ]]; then COMPREPLY=($(compgen -W "$(for i in @GENTOO_PORTAGE_EPREFIX@/etc/runlevels/*; do echo ${i##*/}; done)" -- $cur)) fi return 0 } && complete -F _rc rc # # rc-status completion command # _rcstatus() { local cur cur="${COMP_WORDS[COMP_CWORD]}" if [[ $COMP_CWORD -eq 1 ]]; then if [[ "${cur}" == --* ]]; then COMPREPLY=($(compgen -W '--all --list --unused' -- ${cur})) elif [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W '-a -l -u' -- ${cur})) else COMPREPLY=($(compgen -W "$(rc-status --list)" -- ${cur})) fi else unset COMPREPLY fi return 0 } && complete -F _rcstatus rc-status # # rc-update completion command # _rcupdate() { local cur show COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" if [[ $COMP_CWORD -eq 1 ]]; then if [[ "${cur}" == -* ]]; then COMPREPLY=($(compgen -W '-a -d -s' -- ${cur})) else COMPREPLY=($(compgen -W 'add del show' ${cur})) fi else if [[ "${COMP_WORDS[1]}" == "show" ]] || [[ "${COMP_WORDS[1]}" == "-s" ]]; then show="TRUE" fi if ([[ $COMP_CWORD -eq 3 ]] && [[ -z "$show" ]]) || \ ([[ $COMP_CWORD -eq 2 ]] && [[ -n "$show" ]]) then COMPREPLY=($(compgen -W "$(for i in @GENTOO_PORTAGE_EPREFIX@/etc/runlevels/*; do echo ${i##*/}; done)" -- $cur)) elif [[ $COMP_CWORD -eq 2 ]]; then COMPREPLY=($(compgen -X "*.@(c|sh|test)" -W "$(for i in @GENTOO_PORTAGE_EPREFIX@/etc/init.d/*; do echo ${i##*/}; done)" $cur)) elif [[ ${#COMP_WORDS[*]} -gt 2 ]] ; then COMPREPLY=($(compgen -W "$(for i in @GENTOO_PORTAGE_EPREFIX@/etc/runlevels/*; do echo ${i##*/}; done)" -- $cur)) else unset COMPREPLY fi fi return 0 } && complete -F _rcupdate rc-update # # gcc-config completion command # _gcc_config() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-O --use-old \ -P --use-portage-chost \ -c --get-current-profile \ -l --list-profiles \ -E --print-environ \ -B --get-bin-path \ -L --get-lib-path \ -X --get-stdcxx-incdir" if [[ "${cur}" == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 elif [[ ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) \ $(compgen -W "$(gcc-config -l | sed -r -e 's/(\[([^]]*)\]) //g')" \ -- ${cur}) ) return 0 fi case "${prev}" in -O|--use-old|-P|--use-portage-chost|-c|--get-current-profile|-l|--list-profiles) COMPREPLY=() ;; *) COMPREPLY=( $(compgen -W "\ $(gcc-config -l | sed -r -e 's/(\[([^]]*)\]) //g')" -- ${cur}) ) ;; esac } && complete -F _gcc_config gcc-config # # distcc-config completion command # _distccconfig() { local cur curword numwords opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" numwords=${#COMP_WORDS[*]} curword=${COMP_CWORD} if [[ ${numwords} -gt 3 ]]; then unset COMPREPLY return 0 fi if [[ "${cur}" == -* ]] || [ ${curword} -eq 1 ]; then if [[ ${numwords} -le 2 ]] && [[ ${curword} -eq 1 ]]; then opts="--get-hosts \ --get-verbose \ --get-log \ --set-hosts \ --set-verbose \ --set-log \ --add-path \ --no-path" else opts="" fi else opts="" fi COMPREPLY=($(compgen -W "${opts}" | grep ^$cur)) return 0 } && complete -F _distccconfig distcc-config # # java-config completion command # _javaconfig() { local cur prev curword numwords opts args arg spec flag sedcmd grepcmd local multiplepkgs pkgs execopts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" numwords=${#COMP_WORDS[*]} curword=${COMP_CWORD} opts="" args="" pkgs="" sedcmd="sed -r -e s/\[([^]]+)\].*/\1/" vmsedcmd="sed -r -e s/\[([^]]+)\]/\1/" grepcmd="egrep -o (--set-(system|user)-(classpath|vm)=)" multiplepkgs="" execopts="HtmlConverter JavaPluginControlPanel \ appletviewer awt_robot \ extcheck \ idlj \ j2sdk-config jar jarsigner \ java java-rmi.cgi java_vm javac javadoc javah javap jdb \ keytool kinit klist ktab \ native2ascii \ oldjava oldjavac oldjdb orbd \ policytool \ realpath rmic rmid rmiregistry \ serialver servertool \ tnameserv" if [[ "${cur}" == -* ]] || [ ${curword} -eq 1 ]; then case "${cur}" in --java) opts="--java --javac --java-version" ;; --j@(a@(r|va@(c|-version))|@(dk|re)-home)) opts="" ;; --list-available-@(packages|vms)) opts="" ;; --@(exec|set-@(user|system)-@(classpath|vm))) opts="${cur}=" ;; --set-@(user|system)-@(classpath|vm)=) if [[ "${cur}" == "--set-system-vm=" ]] || [[ "${cur}" == "--set-user-vm=" ]]; then flag="--list-available-vms" args=$(java-config --nocolor "${flag}" | cut --delimiter=' ' --fields=2 | ${vmsedcmd}) else flag="--list-available-packages" args=$(java-config --nocolor "${flag}" | ${sedcmd}) fi for arg in ${args}; do [[ -n "${opts}" ]] && opts="${opts} ${arg}" || opts="${arg}" done COMPREPLY=($(compgen $nospace -W "${opts}")) return 0 ;; --exec=) COMPREPLY=($(compgen $nospace -W "${execopts}")) return 0 ;; *) if [[ "${cur}" == "--set-system-vm="* ]] || [[ "${cur}" == "--set-user-vm="* ]]; then args=$(java-config --nocolor --list-available-vms | cut --delimiter=' ' --fields=2 | ${vmsedcmd}) if [[ "${cur}" == "--set-system-vm="* ]]; then spec=${cur##--set-system-vm=} else spec=${cur##--set-user-vm=} fi for arg in ${args}; do if [[ "${arg:0:${#spec}}" == "${spec}" ]]; then [[ -n "${opts}" ]] && opts="${opts} ${arg}" || opts="${arg}" fi done [[ "${opts}" == "${spec}" ]] && opts="" COMPREPLY=($(compgen -W "${opts}")) return 0 elif [[ "${cur}" == "--set-system-classpath="* ]] || [[ "${cur}" == "--set-user-classpath="* ]]; then args=$(java-config --nocolor --list-available-packages | ${sedcmd}) [[ $(echo "${cur}" | grep -c ",") -gt 0 ]] && multiplepkgs="true" if [[ "${cur}" == "--set-system-classpath="* ]]; then spec="${cur##--set-system-classpath=}" else spec="${cur##--set-user-classpath=}" fi if [[ -n "${multiplepkgs}" ]]; then pkgs="${spec%,*}" spec="${spec##*,}" fi if [[ -n "${multiplepkgs}" ]]; then for arg in ${args}; do if [[ "${spec}" ]]; then if [[ "${arg:0:${#spec}}" == "${spec}" ]] \ && [[ ! $(echo "${cur}" | egrep -o "(=|,)${arg},") ]] then [[ -n "${opts}" ]] && opts="${opts} ${pkgs},${arg}" || opts="${pkgs},${arg}" fi else if [[ ! $(echo "${cur}" | egrep -o "(=|,)${arg},") ]]; then [[ -n "${opts}" ]] && opts="${opts} ${pkgs},${arg}" || opts="${pkgs},${arg}" fi fi done [[ "${opts}" == "${pkgs},${spec}" ]] && opts="" else for arg in ${args}; do if [[ "${spec}" ]] && [[ "${arg:0:${#spec}}" == "${spec}" ]]; then [[ -n "${opts}" ]] && opts="${opts} ${arg}" || opts="${arg}" fi done [[ "${opts}" == "${spec}" ]] && opts="" fi COMPREPLY=($(compgen -W "${opts}")) return 0 elif [[ "${cur}" == "--exec="* ]]; then spec=${cur##--exec=} for arg in ${execopts}; do if [[ "${arg:0:${#spec}}" == "${spec}" ]]; then [[ -n "${opts}" ]] && opts="${opts} ${arg}" || opts="${arg}" fi done [[ "${opts}" == "${spec}" ]] && opts="" COMPREPLY=($(compgen -W "${opts}")) return 0 else opts="--classpath --clean-system-classpath --clean-user-classpath \ --exec \ --full-classpath \ --jar --java --javac --java-version --jdk-home --jre-home \ --list-available-packages --list-available-vms \ --nocolor \ --set-system-classpath --set-system-vm --set-user-classpath --set-user-vm" [[ "$prev" == "--nocolor" ]] && opts="${opts/--nocolor}" fi ;; esac elif [[ "$prev" == "--nocolor" ]] && [ ${curword} -eq 2 ] && [ $numwords -le 3 ]; then opts="--classpath --clean-system-classpath --clean-user-classpath \ --exec \ --full-classpath \ --jar --java --javac --java-version --jdk-home --jre-home \ --list-available-packages --list-available-vms \ --set-system-classpath --set-system-vm --set-user-classpath --set-user-vm" fi COMPREPLY=($(compgen $nospace -W "${opts}" -- ${cur})) return 0 } && complete $nospace -F _javaconfig java-config # # browser-config completion command # _browserconfig() { local cur prev COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" if [[ ${COMP_CWORD} -eq 1 ]]; then COMPREPLY=($(compgen -W '-b -h -m' -- ${cur})) elif [[ "${prev}" == "-b" ]]; then COMPREPLY=($(compgen -W "$(for i in @GENTOO_PORTAGE_EPREFIX@/usr/share/browser-config/*; do [ -f $i ] && echo ${i##*/}; done)" $cur)) elif [[ "${prev}" == "-m" ]]; then COMPREPLY=($(compgen -W "same_window new_window new_tab new_browser" -- ${cur})) if [[ -z "${COMPREPLY}" ]]; then COMPREPLY='' fi else unset COMPREPLY fi return 0 } && complete -F _browserconfig browser-config # # Helper routine for the subcommand 'meta' of 'equery' # (Used two times, by _equery and _epkginfo, therefore in an extra function) # _equery_meta() { local cur="$1" case $cur in -*) COMPREPLY=($(compgen -W "--help -h --description -d --herd -H --keywords -k --maintainer -m --useflags -u --upstream -U --xml -x" -- $cur)) ;; *) _pkgname -A $cur ;; esac } # # Bash completion for the Gentoo 'equery' command # _equery() { local cur prev mode portdir i j portdir=$(_portdir) mode="GLOBAL" COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" # Find out what we're currently doing here. j=0 for i in "${COMP_WORDS[@]}"; do if [[ $j -lt $COMP_CWORD ]]; then j=$((j + 1)) case $i in @(belongs|ch@(anges|eck)|dep@(ends|graph)|files|has?(use)|keywords|list|meta|size|uses|which|b|c|k|d|g|f|a|h|y|l|m|s|u|w)) mode=$i ;; esac fi done # Now get to work. case $mode in GLOBAL) # Complete commands and global options. case $cur in -*) COMPREPLY=($(compgen -W "-q --quiet -C --nocolor -h --help -V --version" -- $cur)) ;; *) COMPREPLY=($(compgen -W "belongs changes check depends depgraph files has hasuse keywords list meta size uses which" -- $cur)) ;; esac ;; c?(hanges)) # Complete package name only if it is not yet supplied. if [[ ${prev} == ${mode} ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help" -- $cur)) ;; *) _pkgname -A $cur ;; esac else case $cur in *) COMPREPLY=($(compgen -W "-h --help -l --latest -f --full --limit --from --to" -- $cur)) ;; esac fi ;; f?(iles)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then # --filter=: completion of the files types list if [[ ${prev} == "-f" || "${cur}" == "--filter="* ]] ; then COMPREPLY=($(_list_compgen "${cur#--filter=}" , \ dir,obj,sym,dev,fifo,path,conf,cmd,doc,man,info)) return 0 fi case $cur in --f*) # don't handle --filter= with others to avoid space after the "=" COMPREPLY=($(compgen -P "--filter=" \ -W "dir obj sym dev fifo path conf cmd doc man info")) ;; -*) COMPREPLY=($(compgen -W "-h --help -m --md5sum -s --timestamp -t --type --tree -f --filter=" -- $cur)) ;; *) # Only installed packages can have their files listed. _pkgname -I $cur ;; esac fi ;; a|has) COMPREPLY=($(compgen -W "-h --help -I --exclude-installed -o \ --overlay-tree -p --portage-tree -F --format" -- $cur)) ;; y|keywords) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case "${cur}" in -*) COMPREPLY=($(compgen -W "-h --help -v --version -a --arch -A --align -T --top-position -B --bold -C --color -O --overlays -P --prefix -S --ignore-slot" -- $cur)) ;; *) _pkgname -A $cur ;; esac fi ;; l?(ist)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case "${cur}" in -*) COMPREPLY=($(compgen -W "-h --help -d --duplicates -b --binpkgs-missing -f --full-regex -m --mask-reason -I --exclude-installed -o --overlay-tree -p --portage-tree -F --format" -- $cur)) ;; *) if [[ ${COMP_WORDS[@]} =~ -(p|o) || ${COMP_WORDS[@]} =~ --(portage|overlay)-tree ]]; then _pkgname -A $cur else _pkgname -I $cur fi ;; esac fi ;; b?(elongs)) # Only complete if the previous entry on the command line is not # a file name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help -f --full-regex -e --early-out -n --name-only" -- $cur)) ;; *) COMPREPLY=($(compgen -f -- $cur) \ $(compgen -d -S '/' -- $cur)) ;; esac fi ;; u?(ses)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help -a --all" -- $cur)) ;; *) # Complete on all package names. _pkgname -A $cur ;; esac fi ;; w?(hich)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help -m --include-masked" -- $cur)) ;; *) # Complete on all package names. _pkgname -A $cur ;; esac fi ;; g|depgraph) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help -A --no-atom -M --no-mask -U --no-useflags -l --linear --depth" -- $cur)) ;; *) # Complete on all package names. _pkgname -A $cur ;; esac fi ;; d?(epends)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help -a --all-packages -D --indirect --depth" -- $cur)) ;; *) case $prev in -a|--all-packages) # Complete on all package names. _pkgname -A $cur ;; *) # Complete on installed package names. _pkgname -I $cur ;; esac ;; esac fi ;; m?(eta)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then _equery_meta $cur fi ;; k|check) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} ]]; then case $cur in -*) COMPREPLY=($(compgen -W "${COMPREPLY[@]} -h --help -f --full-regex -o --only-failures" -- ${cur})) ;; *) # Only installed packages can have their integrity verified. _pkgname -I $cur ;; esac fi ;; s?(ize)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "-h --help -b --bytes -f --full-regex" -- $cur)) ;; *) # Only installed packages can have their size calculated. _pkgname -I $cur ;; esac fi ;; h?(asuse)) # Only complete if the previous entry on the command line is not # a package name. if [[ ${prev} == ${mode} || ${prev:0:1} == "-" ]]; then case $cur in -*) COMPREPLY=($(compgen -W "--help -i --installed -I --exclude-installed -p --portage-tree -o --overlay" -- $cur)) ;; *) local glob loc [[ -f ${portdir}/profiles/use.desc ]] || return 0 [[ -f ${portdir}/profiles/use.local.desc ]] || return 0 glob=$(sed -n -e 's/^\([^ ]\+\) - .*$/\1/p' ${portdir}/profiles/use.desc) loc=$(sed -n -e 's/^[^ ]\+:\([^ ]*\) - .*$/\1/p' ${portdir}/profiles/use.local.desc) COMPREPLY=($(compgen -W "$glob $loc" -- $cur)) ;; esac fi ;; esac return 0 } && complete -F _equery equery # # epkginfo completion # _epkginfo() { local cur prev cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" # Only complete if the previous entry on the command line is not # a package name. if [[ ${COMP_CWORD} -eq 1 || ${prev:0:1} == "-" ]]; then _equery_meta $cur fi return 0 } && complete -F _epkginfo epkginfo # # ekeyword completion # _ekeyword() { local cur portdir archl_s archl_u archl_r archl_m arch COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" portdir=$(_portdir) [[ -f ${portdir}/profiles/arch.list ]] || return 0 for arch in all $(< ${portdir}/profiles/arch.list) ; do archl_m="${archl_m} -${arch}" archl_u="${archl_u} ~${arch}" archl_r="${archl_r} ^${arch}" archl_s="${archl_s} ${arch}" done case ${cur} in -*) COMPREPLY=($(compgen -W "${archl_m}" -- ${cur})) ;; ~*) COMPREPLY=($(compgen -W "${archl_u}" -- ${cur})) ;; ^*) COMPREPLY=($(compgen -W "${archl_r}" -- ${cur})) ;; *) COMPREPLY=($(compgen -W "${archl_s}" -- ${cur})) _filedir 'ebuild' ;; esac } && complete -o filenames -F _ekeyword ekeyword # # portageq completion # _portageq() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="config_protect_mask \ config_protect \ vdb_path \ gentoo_mirrors \ all_best_visible \ match \ best_visible \ mass_best_visible \ has_version \ portdir \ envvar \ mass_best_version \ best_version \ pkgdir \ portdir_overlay \ distdir" if [[ $COMP_CWORD -eq 1 ]] ; then # would always be correct, but it's pretty slow... #COMPREPLY=($(compgen -W "$(portageq | grep '^ [[:lower:]]' | \ # sed -e 's/^.*[[:space:]]\([[:lower:]_]\+\)[[:space:]].*$/\1/')" \ # -- ${cur})) COMPREPLY=($(compgen -W "${opts}" -- ${cur})) fi case "${prev}" in config*|vdb_path|gentoo_mirrors|*dir*) COMPREPLY=() ;; # this also isn't the fastest, but I welcome an alternative method envvar) COMPREPLY=($(compgen -W "$(env -i emerge -v --info | \ sed -n -e '/^[[:upper:]].*=".*"/s/^\(.*\)=".*$/\1/p')" -- ${cur})) ;; *v@(isible|ersion)|match) COMPREPLY=($(compgen $nospace -W '/' -- $cur)) ;; # $prev is a path, so complete on category/package */*) local x a=0 for x in ${COMP_WORDS[@]} ; do # This is the only one if [[ "${x}" == "all_best_visible" ]] ; then a=1 break fi done if [[ ${a} -eq 1 ]] ; then COMPREPLY=() else # Check for conditional. # cond="${cur%%[A-Za-z0-9]*}" # cur="${cur:${#cond}}" # if [[ -n "${cond}" ]] ; then # _pkgname -A $cur # else _pkgname -A $cur # fi fi ;; esac } && complete -F _portageq portageq # # webapp-config completion # _webapp_complete_appver() { local x proot ibase cur="$2" eval $(. @GENTOO_PORTAGE_EPREFIX@/etc/vhosts/webapp-config ; \ echo proot="${MY_PERSISTROOT:-@GENTOO_PORTAGE_EPREFIX@/var/db/webapps}" ; \ echo ibase="${WA_INSTALLSBASE:-installs}") case "$1" in # complete on installed installed) COMPREPLY=($(compgen -W "$(\ for x in ${proot}/*/*/installs ; do \ if [[ -f "${x}" ]] ; then \ local y="${x%/*}" ; \ y="${y%/*}" ; \ echo "${y##*/}" ; \ fi ; \ done)" -- ${cur})) ;; # complete on uninstalled uninstalled) COMPREPLY=($(compgen -W "$(\ for x in ${proot}/*/* ; do \ if [[ ! -f "${x}/${ibase}" ]] ; then \ local y="${x%/*}" ; \ echo "${y##*/}" ; \ fi ; \ done)" -- ${cur})) ;; # all all) COMPREPLY=($(compgen -W "$(\ for x in ${proot}/* ; do \ [[ -d "${x}" ]] && echo "${x##*/}" ; \ done)" -- ${cur})) ;; # complete on version *) [[ -d "${proot}/$1" ]] || return 1 COMPREPLY=($(compgen -W "$(\ for x in ${proot}/$1/* ; do \ [[ -d "${x}" ]] && echo "${x##*/}" ; \ done)" -- ${cur})) ;; esac } _webapp_config() { local cur prev actions opts hostroot COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" actions="-I --install -U --upgrade -C --clean --list-installs \ --list-unused-installs --show-installed --show-postinst \ --help -v --version" opts="--bug-report --pretend -p -u --user -g --group \ -d --dir -h --host -V --verbose --soft --secure --virtual-dirs \ --virtual-files --force-virtual" eval $(. @GENTOO_PORTAGE_EPREFIX@/etc/vhosts/webapp-config ; \ echo hostroot="${VHOST_ROOT:-@GENTOO_PORTAGE_EPREFIX@/var/www}") # --bug-report, --pretend, and -p can only be used as first arg if [[ ${COMP_CWORD} -gt 1 ]] ; then opts="${opts/--bug-report --pretend -p}" fi if [[ "${cur}" == -* ]] || [[ ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=($(compgen -W "${opts} ${actions}" -- ${cur})) return 0 fi case "${prev}" in --bug-report|-p|--pretend) COMPREPLY=($(compgen -W "${opts} ${actions}" -- ${cur})) ;; -I|--install) _webapp_complete_appver all ${cur} ;; -U|--upgrade) _webapp_complete_appver installed ${cur} ;; # only complete on -d since it is required if -C is specified -C|--clean) COMPREPLY=($(compgen -W "-d" -- ${cur})) ;; --list-unused-installs) _webapp_complete_appver uninstalled ${cur} ;; --list-installs|--show-postinst) _webapp_complete_appver all ${cur} ;; # hrm... anyone know a better way to reliably do this? -h|--host) local x COMPREPLY=($(compgen -W "$(\ for x in ${hostroot}/* ; do \ [[ -d "${x}" ]] && echo "${x##*/}" ; \ done)" -- ${cur})) ;; --virtual*) COMPREPLY=($(compgen -W "server-owned config-owned virtual" \ -- ${cur})) ;; -d|--dir) local host x i=0 # see if --host has been specified, and if so, get the value # that was passed to it. for x in ${COMP_WORDS[@]} ; do if [[ "${x}" == "-h" || "${x}" == "--host" ]] ; then host="${COMP_WORDS[((i+1))]}" break fi i=$((i+1)) done # otherwise, use the default host if [[ "${host}" == "" ]] ; then eval $(. @GENTOO_PORTAGE_EPREFIX@/etc/vhosts/webapp-config ; \ echo host="${VHOST_HOSTNAME:-localhost}") fi COMPREPLY=($(compgen -W "$(\ for x in ${hostroot}${host}/* ; do \ [[ -d "${x}" ]] && echo "${x}" ; \ done)" -- ${cur})) ;; -u|--user) COMPREPLY=($(compgen -u -- ${cur})) ;; -g|--group) COMPREPLY=($(compgen -g -- ${cur})) ;; # we haven't recognized it yet, so more than likely ${prev} # is a 'app-name' ; assuming it is indeed a valid 'app-name' # (_webapp_complete_appver does the check), complete on available # 'app-version's *) _webapp_complete_appver ${prev} ${cur} || \ _webapp_complete_appver all ${cur} ;; esac } && complete -F _webapp_config webapp-config _revdep_rebuild() { local cur prev numwords opts local words i x local action actionpos COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" numwords=${#COMP_WORDS[*]} if [[ ${prev} == '>' || ${prev} == '<' ]] ; then COMPREPLY=($(compgen -f -- ${cur})) return 0 fi # find action for ((i = 0; i < ${numwords}; i++ )); do case ${COMP_WORDS[${i}]} in --library|-L) action=${COMP_WORDS[${i}]} actionpos=${i} ;; --help|-h) action=${COMP_WORDS[${i}]} actionpos=${i} ;; esac done if [[ ${cur} == -* ]]; then if [[ ${cur} == --* ]]; then opts="--exact --help --ignore --keep-temp --library --nocolor --no-ld-path --no-order --no-progress --no-util --pretend --quiet --verbose" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) else opts="-e -h -i -k -L -l -o -p -P -q -u -v" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) fi return 0 fi if [[ ${action} == '--library' ]] || [[ ${action} == '-L' ]] ; then if [[ "${cur}" == */* ]]; then COMPREPLY=( $(builtin cd @GENTOO_PORTAGE_EPREFIX@/lib; compgen -f -- "${cur}") ) else COMPREPLY=( $(builtin cd @GENTOO_PORTAGE_EPREFIX@/lib; compgen -X '/' -f -- "${cur}") ) fi fi return 0 } && complete -F _revdep_rebuild revdep-rebuild _splat() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h --help -v --verbose -s --summary -f --logfile -c --colored -l --list -u --count -p --package -t --sort -r --reverse" if [[ ${cur} == -* ]] ; then COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 fi case "${prev}" in -f|--logfile) COMPREPLY=($(compgen -f -- ${cur})) ;; *) _pkgname -A ${cur} COMPREPLY=($(compgen -W "${COMPREPLY[@]} ${opts}" -- ${cur})) ;; esac } && complete -o filenames -F _splat splat _euse() { local cur prev opts sopts use portdir COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="-h --help -v --version -i --info -I --info-installed -a --active -E --enable -D --disable -P --prune" sopts="-g --global -l --local" if [[ ${cur} == -* ]] && [[ ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 fi case "${prev}" in -h|--help|-v|--version) COMPREPLY=() ;; -a|--active) COMPREPLY=($(compgen -W "${sopts}" -- ${cur})) ;; -i|--info|-I|--info-installed|-E|--enable|-D|--disable|-P|--prune) portdir=$(_portdir) use="$(sed -n -e 's/^\([^ ]\+\) - .*$/\1/p' ${portdir}/profiles/use.desc) \ $(sed -n -e 's/^[^ ]\+:\([^ ]*\) - .*$/\1/p' ${portdir}/profiles/use.local.desc)" COMPREPLY=($(compgen -W "${use} ${sopts}" -- ${cur})) ;; *) local l=0 g=0 if [[ ${COMP_LINE} == *" "@(-l|--local)* ]] ; then l=1 elif [[ ${COMP_LINE} == *" "@(-g|--global)* ]] ; then g=1 fi if [[ ${COMP_LINE} == *" "@(-i|--info|-I|--info-installed|-E|--enable|-D|--disable|-P|--prune)* ]] then portdir=$(_portdir) if [[ ${l} -eq 1 ]] ; then use=$(sed -n -e 's/^[^ ]\+:\([^ ]*\) - .*$/\1/p' ${portdir}/profiles/use.local.desc) elif [[ ${g} -eq 1 ]] ; then use=$(sed -n -e 's/^\([^ ]\+\) - .*$/\1/p' ${portdir}/profiles/use.desc) fi COMPREPLY=($(compgen -W "${use}" -- ${cur})) fi esac } && complete -F _euse euse _glsa_check() { local cur opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" opts="-l --list -d --dump --print -t --test -p --pretend -f --fix -i --inject -n --nocolor -e --emergelike -h --help -V --version -v --verbose -c --cve -m --mail" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 fi # too slow otherwise if [[ ! -f ${ROOT}/tmp/gc.out ]] || \ [[ $(stat ${ROOT}/tmp/gc.out | \ sed -n -e 's/^Modify: \([[:digit:]]\+-[[:digit:]]\+-[[:digit:]]\+\).*$/\1/p') != "$(date +%F)" ]] then glsa-check -nl 2>/dev/null | \ sed -n -e 's/^\([[:digit:]]\+-[[:digit:]]\+\) .*$/\1/p' > \ ${ROOT}/tmp/gc.out fi COMPREPLY=($(compgen -W "${opts} $(< ${ROOT}/tmp/gc.out)" -- ${cur})) } && complete -F _glsa_check glsa-check _epm() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD]}" opts="-q --query -V -y --verify -e --erase --help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=($(compgen -W "${opts}" -- ${cur})) return 0 fi case "${prev}" in --help) COMPREPLY=() ;; -q|--query) _pkgname -I ${cur} COMPREPLY=($(compgen -W "${COMPREPLY[@]} -l -f -G -a" -- ${cur})) ;; *) local x all=0 file=0 for x in ${COMP_WORDS[@]} ; do [[ ${x} == -* ]] || continue [[ ${x} == *f* ]] && file=1 [[ ${x} == *a* ]] && all=1 done if [[ ${file} -eq 1 ]] ; then COMPREPLY=($(compgen -f -- ${cur})) elif [[ ${all} -eq 1 ]] ; then COMPREPLY=() else _pkgname -I ${cur} fi ;; esac } && complete -o filenames -F _epm epm _metagen() { local cur prev opts COMPREPLY=() _get_comp_words_by_ref cur prev opts="$(_parse_help ${COMP_WORDS[0]})" case $prev in -h|--help|--version) return 0 ;; -H|-e|-n|-d|-l) return 0 ;; -o) _filedir return 0 ;; esac COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 } && complete -F _metagen metagen _rc_service() { local cur prev numwords opts local words i x filename local action actionpos COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" numwords=${#COMP_WORDS[*]} if [[ ${prev} == '>' || ${prev} == '<' ]] ; then COMPREPLY=($(compgen -f -- ${cur})) return 0 fi # find action for x in ${COMP_LINE} ; do if [[ ${x} =~ --(list|exists|resolve) ]] || \ [[ ${x} =~ -(l|e|r) ]] then action=${x} break fi done if [[ -n ${action} ]]; then for ((i = 0; i < ${numwords}; i++ )); do if [[ ${COMP_WORDS[${i}]} == "${action}" ]]; then actionpos=${i} break fi done for ((i = 1; i < ${numwords}; i++ )); do if [[ ! ${COMP_WORDS[$i]} == -* ]]; then break fi done fi if [[ ${COMP_CWORD} -eq 3 ]]; then return 1 fi # check if an option was typed if [[ ${cur} == -* ]]; then if [[ ${cur} == --* ]]; then opts="--list --exists --resolve" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 elif [[ ${cur} == -* ]]; then opts="-l -e -r" COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi # NOTE: This slows things down! # (Adapted from bash_completion by Ian Macdonald ) # This removes any options from the list of completions that have # already been specified on the command line. COMPREPLY=($(echo "${COMP_WORDS[@]}" | \ (while read -d ' ' i; do [[ -z ${i} ]] && continue # flatten array with spaces on either side, # otherwise we cannot grep on word boundaries of # first and last word COMPREPLY=" ${COMPREPLY[@]} " # remove word from list of completions COMPREPLY=(${COMPREPLY/ ${i%% *} / }) done echo ${COMPREPLY[@]}))) return 0 # if no option typed else if [[ ${COMP_CWORD} -eq 1 ]]; then # if first word typed words="`rc-service -l | grep ^${cur}`" # complete for init scripts COMPREPLY=($(for i in ${words} ; do \ [[ ${i} == ${cur}* ]] && echo ${i} ; \ done)) return 0 elif [[ ${COMP_CWORD} -eq 2 ]] && [[ ${prev} != -* ]]; then # if second word typed and we didn't type in a function filename=`rc-service -r ${prev}` opts=`cat ${filename} | grep "^\w*()" | sed "s/().*$//"` # Greps the functions included in the init script if [[ "x${opts}" == "x" ]] ; then # if no options found loosen the grep algorhythm opts=`cat ${filename} | grep "\w*()" | sed "s/().*$//"` fi COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi fi if [[ ${action} == '--exists' ]] || [[ ${action} == '-e' ]] || \ [[ ${action} == '--resolve' ]] || [[ ${action} == '-r' ]]; then words="`rc-service -l | grep ^${cur}`" COMPREPLY=($(for i in ${words} ; do \ [[ ${i} == ${cur}* ]] && echo ${i} ; \ done)) return 0 fi return 0 } && complete -F _rc_service rc-service # vim: ft=sh:et:ts=4:sw=4:tw=80