diff options
author | Michał Górny <mgorny@gentoo.org> | 2014-08-31 20:49:57 +0200 |
---|---|---|
committer | Michał Górny <mgorny@gentoo.org> | 2014-08-31 21:18:12 +0200 |
commit | 238b95dfeb8f32f592756797786a998b0f07c748 (patch) | |
tree | 736f5d9ebf66123fc07cc9bf32709d61b16f7bc5 /completions | |
parent | Move completions into subdirectories. (diff) | |
download | gentoo-bashcomp-238b95dfeb8f32f592756797786a998b0f07c748.tar.gz gentoo-bashcomp-238b95dfeb8f32f592756797786a998b0f07c748.tar.bz2 gentoo-bashcomp-238b95dfeb8f32f592756797786a998b0f07c748.zip |
Split common functions out of completions.
The goal is to install the reusable functions in helpersdir from where
they can be reused by other completions.
Diffstat (limited to 'completions')
-rw-r--r-- | completions/gentoo | 390 |
1 files changed, 1 insertions, 389 deletions
diff --git a/completions/gentoo b/completions/gentoo index 0e54841..30a1eb1 100644 --- a/completions/gentoo +++ b/completions/gentoo @@ -3,377 +3,7 @@ # 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] <repo> <variable> -# -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 <mode> <current-directory> -# -# 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 <list>" / "--option=<list>" -# kind of command lines options. -# -# Usage: _list_compgen <current> <sep> <item1>[<sep><item2> ...] -# - <current>: what we have so far on the command line -# - <sep>: the separator character used in lists -# - <itemN>: 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 <sep> 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 "<current><sep><other_item>" possible - # completions that should be listed in case <current> 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 <sep>). - # Setting it to a positive value N means "list up to N possible items, and - # only suggest <sep> 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 <sep> 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 <current_item> - # - already used in the list prefix - # - not used in the list prefix, and not an exact match of <current_item> - # Also check whether the <current_item> 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 <current_item>: 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 <current_item>: 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 <current_item> 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 <current_item> 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 "<current>". - my_compreply[${i}]="${current}" - let i++ - fi - if [[ -n "${matching_items}" ]] ; then - # Found some matching items? - # Then add "<prefix_items><matching_item>". - 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 "<current><sep><other_item>" completions. - for my_item in ${other_items} ; do - my_compreply[${i}]="${current}${sep}${my_item}" - let i++ - done - else # Only suggest adding the <sep> 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 -} +source "@helpersdir@/gentoo-common.sh" # # emerge completion command @@ -1128,24 +758,6 @@ _browserconfig() 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() |