commit:     ba66a09a2469e12799995a24b5f59aa718df8f38
Author:     =?UTF-8?q?Felix=20Neum=C3=A4rker?= <xdch47 <AT> posteo <DOT> de>
AuthorDate: Wed Feb 20 20:18:05 2019 +0000
Commit:     Vadim Misbakh-Soloviov <mva <AT> gentoo <DOT> org>
CommitDate: Wed Feb 19 17:51:33 2020 +0000
URL:        
https://gitweb.gentoo.org/proj/zsh-completion.git/commit/?id=ba66a09a

Merge Pull Request #18 (squashed)

[PATCH 1/6] _gentoo_repos: split functions into 2 files
[PATCH 2/6] _portage: improve completion for ebuild and emaint
[PATCH 3/6] _eselect: rewrite for more generic completion
[PATCH 4/6] add EPREFIX support
[PATCH 5/6] _eselect: multi_parts timezone completion
[PATCH 6/6] _eselect: set/enable filter for lists > 10

Signed-off-by: Vadim A. Misbakh-Soloviov <git <AT> mva.name>

 src/_eselect           | 363 +++++++++++++++++++++++++++----------------------
 src/_gentoo_packages   |  28 ++--
 src/_gentoo_repos      |  64 ++-------
 src/_gentoo_repos_conf |  55 ++++++++
 src/_gentoolkit        |   4 +-
 src/_portage           | 145 ++++++++++++++++----
 src/_portage_utils     |   4 +-
 7 files changed, 396 insertions(+), 267 deletions(-)

diff --git a/src/_eselect b/src/_eselect
index 46b8477..77b9fd6 100644
--- a/src/_eselect
+++ b/src/_eselect
@@ -1,199 +1,232 @@
-#compdef eselect
-
-common_values=(
-  "help[Display help text]"
-  "usage[Display usage information]"
-  "version[Display version information]"
-)
-
-_eselect_env () {
-  if (( $words[(I)(update)] )); then
-    _values "update options" \
-      "makelinks[force updating of links]" \
-      "noldconfig[Do not alter the ld.so cache or configuration]" && return 0
+#compdef eselect kernel-config profile-config rc-config
+
+_eselect_parse_generic() {
+  local -a mod_std mod_extra
+  local -a eselect_args
+  local mod_cur eselect_descr
+  local mod descr etype
+
+  eselect_args=($@)
+  if [[ $1 == "modules" ]] ; then
+    eselect_args=($1 usage)
   fi
-  _values "env options" $common_values \
-    'update[Collect environment variables from all scripts in /etc/env.d/]' && 
return 0
-}
+  mod_cur="mod_extra"
+  eselect_descr="$(LANG=C COLUMNS=100 eselect --colour=no ${eselect_args[@]} 
2> /dev/null)"
+
+  while IFS="" read -r helpdesc ; do
+    case "$helpdesc" in
+      ("Built-in modules:"|"Standard actions:"))
+        mod_cur="mod_std"
+        ;;
+      ("Extra modules:"|"Extra actions:"))
+        mod_cur="mod_extra"
+        ;;
+    esac
+
+    if [[ "$helpdesc" =~ '^  [A-Za-z]' ]] ; then
+      echo "$helpdesc" | read mod descr
+      descr="$(echo "$descr" | sed -r -e 's/.*\s\s\s+//')"
+      set -A $mod_cur ${(P)mod_cur} ${mod}:${(q)descr}
+    fi
+  done <<< "$eselect_descr"
 
-_eselect_binutils () {
-  local binutilslist
-  if (( $words[(I)(set)] )); then
-    binutilslist=(${(f)"$(eselect --brief --color=no binutils list)"})
-    _values "available binutils version" $binutilslist[@] && return 0
+  if [[ -z "${eselect_args[@]}" ]] ; then
+    etype="modules"
+  else
+    etype="actions"
   fi
-  _values "binutils options" $common_values \
-    "list[List all installed version of binutils]" \
-    "show[Print the currently active binutils version]" \
-    "set[Activate one of the installed binutils]" && return 0
-}
 
-_eselect_kernel () {
-  local kernellist
-  if (( $words[(I)(set)] )); then
-    kernellist=(${(f)"$(eselect --brief --color=no kernel list)"})
-    _values "available kernel version" $kernellist[@] && return 0
+  if [[ -z "${mod_extra}" && -z "${mod_std}" ]] ; then
+    _nothing
+  else
+    _describe -t eselect_extra    -V "eselect extra $etype"    mod_extra
+    _describe -t eselect_standard -V "eselect standard $etype" mod_std
   fi
-  _values "kernel options" $common_values \
-    "list[List available kernel symlink targets]" \
-    "show[Show the current kernel symlink]" \
-    "set[Set a new kernel symlink target]" && return 0
 }
 
-_eselect_ctags () {
-  local ctagslist
-  if (( $words[(I)(set)] )); then
-    ctagslist=(${(f)"$(eselect --brief --color=no ctags list)"})
-    _values "available ctags version" $ctagslist[@] && return 0
+_eselect_parse_action_list() {
+  local eselect_list
+  local idx descr
+  local arr_items_selected=$2
+  local arr_items_unselected=$3
+
+  eselect_list="$(LANG=C COLUMNS=100 eselect --colour=no $1 list 2> /dev/null)"
+  while IFS="" read -r ele ; do
+    echo "$ele" | read idx descr
+    idx=${idx#*\[}
+    idx=${idx%\]*}
+    if [[ "$idx" =~ '^[0-9]+$' ]]; then
+      local stripped_descr="${descr% *\**}"
+      if [[ "${stripped_descr}" != "${descr}" ]] ; then
+        set -A $arr_items_selected ${(P)arr_items_selected} "$idx:${(q)descr}"
+      else
+        set -A $arr_items_unselected ${(P)arr_items_unselected} 
"$idx:${(q)descr}"
+      fi
+    fi
+  done <<< "$eselect_list"
+}
+
+_eselect_module_action() {
+  if (( $+functions[_eselect_${1}_action] )) ; then
+    _eselect_${1}_action
+  else
+    _eselect_parse_generic ${1}
   fi
-  _values "ctags options" $common_values \
-    "list[List available ctags symlink targets]" \
-    "show[Show the current target of the ctags symlink]" \
-    "update[Automatically update the ctags symlink]" \
-    "set[Set a new ctags symlink target]" && return 0
 }
 
-_eselect_profile () {
-  local profilelist
-  if (( $words[(I)(set)] )); then
-    profilelist=(${${(f)"$(eselect --brief --color=no profile list)"}/:/\\:})
-    _values -w "available profiles" $profilelist[@] \
-      "--force[Forcibly set the symlink]" && return 0
+_eselect_complete_action() {
+  local actionname=$(_eselect_get_module)
+  if (( $+functions[_eselect_complete_${actionname}_action] )) ; then
+    _eselect_complete_${actionname}_action
+  else
+    _eselect_complete_action_generic ${actionname}
   fi
-  _values "profile options" $common_values \
-    "list[List available profile symlink targets]" \
-    "show[Show the current make.profile symlink]" \
-    "set[Set a new profile symlink target]" && return 0
 }
 
-_eselect_fontconfig () {
-  local fclistenabled fclistdisabled
-  if (( $words[(I)(enable)] )); then
-    fclistdisabled=(${${${${(M)${(f)"$(eselect --color=no fontconfig list)"}## 
*}#*\*}// \**/}//(  \[*\]   |  \[*\]  )/})
-    _values -w ".conf to enable" $fclistdisabled[@] && return 0
-  elif (( $words[(I)(disable)] )); then
-    fclistenabled=(${${${(M)${(M)${(f)"$(eselect --color=no fontconfig 
list)"}## *}#*\*}// \**/}//(  \[*\]   |  \[*\]  )/})
-    _values -w ".conf to disable" $fclistenabled[@] && return 0
+_eselect_get_module() {
+  if [[ $service == "eselect" ]] ; then
+    echo $line[1]
+  else
+    echo ${service%-config}
   fi
-  _values "fontconfig options" $common_values \
-    "list[List available fontconfig .conf files]" \
-    "disable[Disable specified fontconfig .conf file(s)]" \
-    "enable[Enable specified fontconfig .conf file(s)]" && return 0
 }
 
-_eselect_opengl () {
-  local opengllist
-  if (( $words[(I)(set)] )); then
-    opengllist=(${(f)"$(eselect --brief --color=no opengl list)"})
-    _values -w "opengl implementations and options" $opengllist[@] \
-      "--use-old[If an implementation is already set, use that one instead]" \
-      "--prefix[Set the source prefix]:path:_files -/" \
-      "--dst-prefix[Set the destination prefix]:path:_files -/" \
-      "--ignore-missing[Ignore missing files when setting a new 
implementation]" && return 0
+_eselect_action_index() {
+  if [[ $service == "eselect" ]] ; then
+    echo 2
+  else
+    echo 1
   fi
-  _values "opengl options" $common_values \
-    "list[List the available OpenGL implementations]" \
-    "set[Select the OpenGL implementation]" \
-    "show[Print the current OpenGL implementation]" && return 0
+}
+_eselect_get_action () {
+  echo ${line[$(_eselect_action_index)]}
+}
+
+_eselect_action() {
+  _eselect_module_action $(_eselect_get_module)
+}
+
+_eselect_module() {
+  _eselect_parse_generic
 }
 
-_eselect_vi () {
-  local vilist
-  if (( $words[(I)(set)] )); then
-    vilist=(${(f)"$(eselect --brief --color=no vi list)"})
-    _values -w "vi implementation" $vilist[@] && return 0
-  elif (( $words[(I)(update)] )); then
-    _values -w "option" "--if-unset[Do not override existing implementation]" 
&& return 0
+_eselect_complete_action_generic() {
+  local -a sel_items
+  local -a unsel_items
+
+  if (( $NORMARG + $(_eselect_action_index) == $CURRENT )) ; then
+    case "$(_eselect_get_action)" in
+      ("set"|"enable"))
+        _eselect_parse_action_list $1 sel_items unsel_items
+          if (( $#unsel_items + $#sel_items > 0 )) ; then
+          _describe -t eselect_sel   -V 'eselect items' unsel_items
+          if (( $#unsel_items + $#sel_items < 10 )) ; then
+            _describe -t eselect_unsel -V 'eselect already selected items' 
sel_items
+          fi
+          return 0
+        fi
+        ;;
+      ("remove"|"disable"))
+        _eselect_parse_action_list $1 sel_items unsel_items
+        if [[ -n "${sel_items[@]}" ]] ; then
+          _describe  -V 'eselect items' sel_items
+          return 0
+        fi
+        ;;
+    esac
   fi
-  _values "vi options" $common_values \
-    "list[List available vi implementations]" \
-    "set[Set a new vi implementation provider]" \
-    "show[Show the current vi implementation]" \
-    "update[Automatically update the vi provider]"
+
+  _nothing
 }
 
-_eselect_news() {
-
-  ## TODO: Normal numeric sorting.
-  ## I've spent many time on trying to rewrite this
-  ## function to normally sort (to DO NOT sort, actually) items,
-  ## but it growing bigger and bigger and going to be too complicated.
-  ## So, I (mva) either need to help to make it in the "right way".
-  ## Or, maybe, to completely rewrite this compdef.
-
-  local -a newslist;
-  if ((CURRENT == 3)); then
-    _values 'news options' $stdopts[@] \
-    'list[List news items]' \
-    'count[Display number of news items]' \
-    'purge[Purge read news]' \
-    'read[Read news items]' \
-    'unread[Mark read news items as unread again]' && return 0
-  elif ((CURRENT == 4)); then
-    if (( $words[(I)(count)] )); then
-    _values -w 'news' 'new[Count only new news items]' 'all[Count all news 
items]' && return 0
-    fi
+# custom completions:
+(( $+functions[_eselect_complete_news_action] )) || 
_eselect_complete_news_action() {
+  local -a items
 
-    newslist=(${${${${${${${(M)${(f)"$(eselect --color=no news list)"}## *}// 
\**/}/  \[/}/\] ##/\[}/%/]}/ \[/ (}/\] /) })
+  case "$(_eselect_get_action)" in
+    ("read"|"unread"))
+      local -a extra_items=('all:Read all news items')
+      if [[ $(_eselect_get_action) == "read" ]] ; then
+        extra_items=('new:Read unread news items (default)' 
"${extra_items[@]}")
+      fi
+      _eselect_parse_action_list news items items
 
-    if (( $words[(I)(read)] )); then
-      newslist+=( "new[Read unread news items (default)]" "all[Read all news 
items]" "--mbox[Output in mbox format]" "--quiet[Suppress output, only change 
status]" "--raw[Output in raw format]" )
-    fi;
+      items=(${(q)extra_items[@]} ${(Oa)items})
+      if [[ -n "${items[@]}" ]] ; then
+        _describe  -V 'eselect items' items
+        return 0
+      fi
+      ;;
+  esac
 
-    if (( $words[(I)(unread)] )); then
-      newslist+=( "all[Unread all news items]" )
-    fi
+  _nothing
+}
 
-    _values -w 'news' $newslist[@] && return 0
+(( $+functions[_eselect_complete_kernel_action] )) || 
_eselect_complete_kernel_action() {
+  local -a items
+
+  if (( $NORMARG + $(_eselect_action_index) == $CURRENT )) ; then
+    case "$(_eselect_get_action)" in
+      "set")
+        for k in ${(@f)$(eselect --colour=no --brief kernel list)} ; do
+          items+=${k#linux-}
+        done
+        local -a expl=(-P linux-)
+        compadd -V  'eselect kernel' -P linux- ${items[@]}
+        return 0
+        ;;
+    esac
   fi
+
+  _nothing
 }
 
-_eselect () {
-  local globopts modnames modopts
-
-  globopts=(
-    "--brief[Make output shorter]"
-    "--colour=no[Disable coloured output]"
-    "--color=no[Disable coloured output]"
-  )
-  modnames=(${${${(M)${(f)"$(eselect --brief --color=no modules list)"}## *}// 
  */}//  /})
-
-  if ((CURRENT == 2)); then
-    _arguments -s \
-      "$globopts[@]" \
-      "*:portage:_values 'eselect modules' \$modnames[@]" && return 0
-  elif ((CURRENT == 3)); then
-    if [[ $words[2] == --colour=no || $words[2] == --color=no ]]; then
-      _arguments -s \
-        "*:portage:_values 'eselect modules' \$modnames[@]" && return 0
-    elif (( $modnames[(I)$words[2]] )); then
-      if [[ "$words[2]" == 
(env|binutils|kernel|ctags|profile|fontconfig|opengl|vi|news) ]]; then
-        _eselect_$words[2] "$@"
-      else
-        modopts=(${${${(M)${(f)"$(eselect --brief --color=no $words[2] 
usage)"}## *}//   */}//  /})
-        _arguments -s \
-          "*:portage:_values 'eselect $words[2] options' \$modopts[@]" && 
return 0
-      fi
-    fi
-  elif ((CURRENT >= 4)); then
-    if (( $words[(I)(--color=no|--colour=no)] )); then
-      if (( $modnames[(I)$words[3]] )); then
-        if [[ "$words[3]" == 
(env|binutils|kernel|ctags|profile|fontconfig|opengl|vi|news) ]]; then
-          _eselect_$words[3] "$@"
-        else
-          modopts=(${${${${(M)${(f)"$(eselect --brief --color=no $words[3] 
usage)"}## *}//   */}//  /}// *})
-          _arguments -s \
-            "*:portage:_values 'eselect $words[3] options' \$modopts[@]" && 
return 0
-        fi
-      fi
-    else
-      if (( $modnames[(I)$words[2]] )); then
-        (( $+functions[_eselect_$words[2]] )) && _eselect_$words[2] "$@"
-      fi
-    fi
+(( $+functions[_eselect_complete_profile_action] )) || 
_eselect_complete_profile_action() {
+  if (( $NORMARG + $(_eselect_action_index) == $CURRENT )) ; then
+    case "$(_eselect_get_action)" in
+      "set")
+        _values  'eselect profiles' $(eselect --colour=no --brief profile list)
+        return 0
+        ;;
+    esac
   fi
+
+  _nothing
+}
+
+(( $+functions[_eselect_complete_timezone_action] )) || 
_eselect_complete_timezone_action() {
+  if (( $NORMARG + $(_eselect_action_index) == $CURRENT )) ; then
+    case "$(_eselect_get_action)" in
+      "set")
+        _multi_parts /  "($(eselect --colour=no --brief timezone list))"
+        return 0
+        ;;
+    esac
+  fi
+
+  _nothing
+}
+
+eselect_comp() {
+  integer NORMARG
+
+  case "$service" in
+    eselect)
+      _arguments -A '-*' -n \
+        '--brief[Make output shorter]' \
+        '(--colour --color)'--colo{,u}r='[Enable or disable colour 
output]:colour:(yes no)' \
+        '1:eselect_module:_eselect_module' \
+        '2:eselect_action:_eselect_action' \
+        '*:eselect_complete_action:_eselect_complete_action'
+      ;;
+    *-config)
+      _arguments -n \
+        "1:action:_eselect_action" \
+        '*:eselect_complete_action:_eselect_complete_action'
+      ;;
+  esac
 }
 
-_eselect "$@"
+eselect_comp "$@"
 
 # vim: set et sw=2 ts=2 ft=zsh:

diff --git a/src/_gentoo_packages b/src/_gentoo_packages
index 37539c8..c2d9d36 100644
--- a/src/_gentoo_packages
+++ b/src/_gentoo_packages
@@ -58,7 +58,7 @@ _parsesetsconf() {
 
 _gentoo_packages_update_installed_sets() {
   local sets
-  sets=($(</var/lib/portage/world_sets))
+  sets=($(<${EPREFIX}/var/lib/portage/world_sets))
   if [[ ((${#sets} > 0)) ]]; then
      _wanted installed_sets expl 'installed set' compadd "$@" "${(o@)^sets}"
   fi
@@ -67,7 +67,7 @@ _gentoo_packages_update_installed_sets() {
 _gentoo_packages_update_available_sets() {
   local dirs dir sets_dir set sets sets_path sets_files
 
-  dirs=($(_gentoo_repos -o) /etc/portage /usr/share/portage/config)
+  dirs=($(_gentoo_repos -o) ${EPREFIX}/etc/portage 
${EPREFIX}/usr/share/portage/config)
 
   for dir in ${(@)dirs}; do
     if [[ -d ${dir} ]]; then
@@ -104,10 +104,10 @@ _gentoo_packages_update_useflag(){
 _gentoo_packages_update_active_useflag(){
   local flags USE
   var=USE
-  [[ -z ${(P)var} && -r /etc/portage/make.conf ]] &&
-    local $var="$(. /etc/portage/make.conf 2>/dev/null; echo ${(P)var})"
-  [[ -z ${(P)var} && -r /etc/make.conf ]] &&
-    local $var="$(. /etc/make.conf 2>/dev/null; echo ${(P)var})"
+  [[ -z ${(P)var} && -r ${EPREFIX}/etc/portage/make.conf ]] &&
+    local $var="$(. ${EPREFIX}/etc/portage/make.conf 2>/dev/null; echo 
${(P)var})"
+  [[ -z ${(P)var} && -r ${EPREFIX}/etc/make.conf ]] &&
+    local $var="$(. ${EPREFIX}/etc/make.conf 2>/dev/null; echo ${(P)var})"
   flags=(${${${=USE}%-*}%\\*})
   compadd $flags
 }
@@ -122,7 +122,7 @@ _gentoo_packages_update_category(){
 
 _gentoo_packages_update_installed(){
    local installed_dir installed_portage installed_pkgname installed_list
-   installed_dir="/var/db/pkg"
+   installed_dir="${EPREFIX}/var/db/pkg"
    installed_portage=($installed_dir/*-*/*)
 
    installed_pkgname=(${${installed_portage:t}%%-[0-9]*})
@@ -135,7 +135,7 @@ _gentoo_packages_update_installed(){
 _gentoo_packages_update_installed_versions(){
   local installed_list installed_portage
 
-  installed_portage=(/var/db/pkg/*-*/*)
+  installed_portage=(${EPREFIX}/var/db/pkg/*-*/*)
   _wanted packages expl 'package' compadd "$@" ${installed_portage:t}
 
   installed_list=(${installed_portage##*/pkg/})
@@ -196,12 +196,12 @@ _gentoo_packages_update_available_versions(){
 _gentoo_packages_update_binary() {
   local PKGDIR
 
-  [[ -z $PKGDIR && -r /etc/portage/make.conf ]] &&
-    PKGDIR="$(. /etc/portage/make.conf 2>/dev/null; echo $PKGDIR)"
-  [[ -z $PKGDIR && -r /etc/make.conf ]] &&
-    PKGDIR="$(. /etc/make.conf 2>/dev/null; echo $PKGDIR)"
-  [[ -z $PKGDIR && -r /usr/share/portage/config/make.globals ]] &&
-    PKGDIR="$(. /usr/share/portage/config/make.globals 2>/dev/null; echo 
$PKGDIR)"
+  [[ -z $PKGDIR && -r ${EPREFIX}/etc/portage/make.conf ]] &&
+    PKGDIR="$(. ${EPREFIX}/etc/portage/make.conf 2>/dev/null; echo $PKGDIR)"
+  [[ -z $PKGDIR && -r ${EPREFIX}/etc/make.conf ]] &&
+    PKGDIR="$(. ${EPREFIX}/etc/make.conf 2>/dev/null; echo $PKGDIR)"
+  [[ -z $PKGDIR && -r ${EPREFIX}/usr/share/portage/config/make.globals ]] &&
+    PKGDIR="$(. ${EPREFIX}/usr/share/portage/config/make.globals 2>/dev/null; 
echo $PKGDIR)"
 
   # this doesn't take care of ${PORTAGE_BINHOST}. If Gentoo official
   # binary mirror will be available we should rewrite it accordingly.

diff --git a/src/_gentoo_repos b/src/_gentoo_repos
index 85f3936..e5acf36 100644
--- a/src/_gentoo_repos
+++ b/src/_gentoo_repos
@@ -11,22 +11,22 @@ _gentoo_repos() {
   overlay_paths=();
   result=();
 
-  if [[ -e /usr/share/portage/config/repos.conf || -e /etc/portage/repos.conf 
]]; then
-    main_repo=$(_repos_conf DEFAULT main-repo)
-    main_repo_path=$(_repos_conf ${main_repo} location)
+  if [[ -e ${EPREFIX}/usr/share/portage/config/repos.conf || -e 
${EPREFIX}/etc/portage/repos.conf ]]; then
+    main_repo=$(_gentoo_repos_conf DEFAULT main-repo)
+    main_repo_path=$(_gentoo_repos_conf ${main_repo} location)
 
-    for overlay in $(_repos_conf -l); do
-      overlay_paths+=($(_repos_conf ${overlay} location))
+    for overlay in $(_gentoo_repos_conf -l); do
+      overlay_paths+=($(_gentoo_repos_conf ${overlay} location))
     done
 
-    source /etc/make.conf 2>/dev/null
-    source /etc/portage/make.conf 2>/dev/null
+    source ${EPREFIX}/etc/make.conf 2>/dev/null
+    source ${EPREFIX}/etc/portage/make.conf 2>/dev/null
 
     overlay_paths+=(${(@)PORTDIR_OVERLAY})
   else
-    source /usr/share/portage/config/make.globals 2>/dev/null
-    source /etc/make.conf 2>/dev/null
-    source /etc/portage/make.conf 2>/dev/null
+    source ${EPREFIX}/usr/share/portage/config/make.globals 2>/dev/null
+    source ${EPREFIX}/etc/make.conf 2>/dev/null
+    source ${EPREFIX}/etc/portage/make.conf 2>/dev/null
 
     main_repo_path="${PORTDIR}"
     overlay_paths=(${(@)PORTDIR_OVERLAY})
@@ -43,50 +43,6 @@ _gentoo_repos() {
   echo ${(u)result}
 }
 
-_repos_conf() {
-  local v file insection section arr secname
-
-  secname=();
-
-  for file in /usr/share/portage/config/repos.conf \
-           /etc/portage/repos.conf \
-           /etc/portage/repos.conf/*.conf; do
-
-    [[ -f ${file} ]] || continue
-    insection=0
-    declare -A arr
-    IFS='= '
-
-    while read -r name value; do
-      [[ -z ${name} || ${name} == '#'* ]] && continue
-
-      if [[ (${name} == '['*']') && (-z ${value}) ]]; then
-        value=${name//(\]|\[)}
-        name="section"
-      fi
-      arr[${name}]=${value}
-
-      if [[ ${insection} == 1 && ${name} == "section" ]]; then
-        break
-      elif [[ ${name} == "section" ]]; then
-        [[ ${value} == ${1} ]] && insection=1
-        secname+=(${value})
-      elif [[ ${insection} == 1 ]]; then
-        if [[ ${name} == ${2} ]]; then
-          v=${value}
-        fi
-      fi
-      continue
-    done < ${file}
-  done
-
-  if [[ ${1} == "-l" ]]; then
-    echo "${(@u)secname}"
-  else
-    echo "${v}"
-  fi
-}
-
 _gentoo_repos "$@"
 
 # vim: set et sw=2 ts=2 ft=zsh:

diff --git a/src/_gentoo_repos_conf b/src/_gentoo_repos_conf
new file mode 100644
index 0000000..3dad709
--- /dev/null
+++ b/src/_gentoo_repos_conf
@@ -0,0 +1,55 @@
+#autoload
+
+# Usage:
+#   _gentoo_repos_conf -l             -> returns the list of all repos names
+#   _gentoo_repos_conf REPO ATTRIBUTE -> returns the VALUE associated 
+#                                        with the ATTRIBUTE of the REPO
+
+_gentoo_repos_conf() {
+  local v file insection section arr secname
+
+  secname=();
+
+
+  for file in ${EPREFIX}/usr/share/portage/config/repos.conf \
+           ${EPREFIX}/etc/portage/repos.conf \
+           ${EPREFIX}/etc/portage/repos.conf/*.conf; do
+
+    [[ -f ${file} ]] || continue
+    insection=0
+    declare -A arr
+    IFS='= '
+
+    while read -r name value; do
+      [[ -z ${name} || ${name} == '#'* ]] && continue
+
+      if [[ (${name} == '['*']') && (-z ${value}) ]]; then
+        value=${name//(\]|\[)}
+        name="section"
+      fi
+      arr[${name}]=${value}
+
+      if [[ ${insection} == 1 && ${name} == "section" ]]; then
+        break
+      elif [[ ${name} == "section" ]]; then
+        [[ ${value} == ${1} ]] && insection=1
+        secname+=(${value})
+      elif [[ ${insection} == 1 ]]; then
+        if [[ ${name} == ${2} ]]; then
+          v=${value}
+        fi
+      fi
+      continue
+    done < ${file}
+  done
+
+  if [[ ${1} == "-l" ]]; then
+    echo "${(@u)secname}"
+  else
+    echo "${v}"
+  fi
+}
+
+_gentoo_repos_conf "$@"
+
+# vim: set et sw=2 ts=2 ft=zsh:

diff --git a/src/_gentoolkit b/src/_gentoolkit
index fdad29f..ce5ada4 100644
--- a/src/_gentoolkit
+++ b/src/_gentoolkit
@@ -204,7 +204,7 @@ _equery () {
           {size,s}'[print size of files contained in package]'
           {uses,u}'[display USE flags for package]'
           {which,w}'[print full path to ebuild for package]'
-          {has,a}'[list all packages matching ENVIRONMENT data stored in 
/var/db/pkg]'
+          {has,a}'[list all installed packages where specified KEY matches the 
specified VALUE]'
           {keywords,y}'[display keywords for specified PKG]'
           {meta,m}'[display metadata about PKG]'
         )
@@ -357,7 +357,7 @@ _glsa_id () {
   # will be low. May be we should display only the X previous GLSA,
   # or GLSA ids of the X last month.
   #
-  # start to look at /usr/lib/gentoolkit/pym/glsa.py if GLSA_DIR is still
+  # start to look at ${EPREFIX}/usr/lib/gentoolkit/pym/glsa.py if GLSA_DIR is 
still
   # PORTDIR + "metadata/glsa/"
   # and then get the list (it's only xml files in GLSA_DIR, easy!)
 

diff --git a/src/_portage b/src/_portage
index 1c43ac4..8700829 100644
--- a/src/_portage
+++ b/src/_portage
@@ -1,33 +1,51 @@
 #compdef emerge ebuild quickpkg emaint env-update etc-update portageq repoman
 
 _ebuild () {
-  if (( CURRENT == 2 )); then
-    _files -g \*.ebuild
-  elif (( CURRENT > 2 )); then
-    _values "ebuild command" \
-      'clean[Cleans the temporary build directory]' \
-      'help[Show help]' \
-      'setup[Run all package specific setup actions and exotic system 
checks.]' \
-      'fetch[Fetch all necessary files]' \
-      'digest[Creates a digest file for the package]' \
-      'unpack[Extracts the sources to a subdirectory in the build directory]' \
-      'prepare[Prepares the extracted sources by running the src_prepare()]' \
-      'configure[Configures the extracted sources by running the 
src_configure()]' \
-      'compile[Compiles the extracted sources by running the src_compile()]' \
-      'test[Runs package-specific test cases to verify that everything was 
built properly]' \
-      'preinst[Run specific actions that need to be done before installation]' 
\
-      'install[Installs the package to the temporary install directory]' \
-      'postinst[Run specific actions that need to be done after installation]' 
\
-      'qmerge[Installs the package de the filesystem]' \
-      'merge[perform the following actions: fetch, unpack, compile, install 
and qmerge.]' \
-      'unmerge[Remove the installed files of the packages]' \
-      'prerm[Run specific actions that need to be executed before unmerge]' \
-      'postrm[Run specific actions that need to be executed after unmerge]' \
-      'config[Run specific actions needed to be executed after the emerge 
process has completed.]' \
-      'package[This command is a lot like the merge command, but create a 
.tbz2 package]' \
-      'manifest[Updates the manifest file for the package.]' \
-      'rpm[Builds a RedHat RPM package]'
-  fi
+  local state
+  local expl=(-Vx)
+  local optional_args=(
+    '--skip-manifest[skip all manifest checks]'
+    '--debug[run bash with the -x option]'
+    '--color=[enable or disable  color  output]:yes/no:((y\:yes n\:no))'
+    '--ignore-default-opts[ignore $EBUILD_DEFAULT_OPTS]'
+    '--force[forces regeneration all associated distfiles if used with digest 
or or manifest command]'
+  )
+
+  _arguments -O expl -C $optional_args "1:ebuild file:_files -g \*.ebuild" 
"*:ebuild command:->ebuild_cmd"
+
+  case $state in
+    (ebuild_cmd)
+
+      local ebuild_cmds=(
+        'clean[Cleans the temporary build directory]'
+        'help[Show help]'
+        'setup[Run all package specific setup actions and exotic system 
checks]'
+        'fetch[Fetch all necessary files]'
+        'digest[Creates a digest file for the package]'
+        'unpack[Extracts the sources to a subdirectory in the build directory]'
+        'prepare[Prepares the extracted sources by running the src_prepare()]'
+        'configure[Configures the extracted sources by running the 
src_configure()]'
+        'compile[Compiles the extracted sources by running the src_compile()]'
+        'test[Runs package-specific test cases to verify that everything was 
built properly]'
+        'preinst[Run specific actions that need to be done before 
installation]'
+        'install[Installs the package to the temporary install directory]'
+        'postinst[Run specific actions that need to be done after 
installation]'
+        'qmerge[Installs the package de the filesystem]'
+        'merge[perform the following actions: fetch, unpack, compile, install 
and qmerge]'
+        'unmerge[Remove the installed files of the packages]'
+        'prerm[Run specific actions that need to be executed before unmerge]'
+        'postrm[Run specific actions that need to be executed after unmerge]'
+        'config[Run specific actions needed to be executed after the emerge 
process has completed]'
+        'package[This command is a lot like the merge command, but create a 
.tbz2 package]'
+        'manifest[Updates the manifest file for the package]'
+        'rpm[Builds a RedHat RPM package]'
+      )
+
+      local curcontext="ebuild_cmd"
+      zstyle -t ":completion:${curcontext}:values:values" sort || zstyle 
":completion:${curcontext}:values:values" sort false
+      _values -w "ebuild command" "$ebuild_cmds[@]"
+      ;;
+  esac
 }
 
 _quickpkg () {
@@ -186,6 +204,8 @@ _emerge () {
     "(: $all[3,-1])--resume[Resumes the last merge operation]"
     "(: $all[3,-1])--skipfirst[Removes the first package in the resume list]"
     "($all)--keep-going[Continue merge even if a package fails to build]"
+    "--with-bdeps=[pull in build time dependencies  that  are  not  strictly  
required]:yes/no:((y\:'yes' n\:'no'))"
+    "--with-test-deps=[pull in dependencies that are conditional  on  the 
\"testUSE flag]:yes/no:((y\:'yes' n\:'no'))"
   )
 
   profiles=(
@@ -235,11 +255,76 @@ _emerge () {
 }
 
 _emaint () {
-  _arguments -s \
+  local state
+  local chk_opt fix_opt pretend_opt clean_opt purge_opt log_extra_opt repo_opt
+  local sync_opt sync_extra_opt standalone_opt exclusive_cmd_opt repos
+  local allcmd logcmd synccmd mergecmd fixcmds
+  chk_opt=(-c --check)
+  fix_opt=(-f --fix)
+  pretend_opt=(-p --pretend)
+  clean_opt=(-C --clean)
+  purge_opt=(-P --purge)
+  log_extra_opt=(-t --time)
+  repo_opt=(-r --repo)
+  sync_opt=(-a --auto -A --allrepos)
+  sync_extra_opt=(--sync-submodule $repo_opt)
+
+  standalone_opt=(-h --help --version)
+  exclusive_cmd_opt=($chk_opt $fix_opt $sync_opt $purge_opt $pretend_opt 
$standalone_opt)
+  repos=$(_gentoo_repos_conf -l)
+
+  _arguments -C \
     "(: -)"{-h,--help}'[show help message and exit]' \
+    "($sync_extra_opt $log_extra_opt $exclusive_cmd_opt 
$clean_opt)"{-f,--fix}"[Fix any problems that may exist]" \
     "(: -)"--version"[show program's version number and exit]" \
-    '(-c --check -f --fix)'{-c,--check}"[Check for any problems that may 
exist]:emaint:((all\:'check all' world\:'check only world file'))" \
-    '(-c --check -f --fix)'{-f,--fix}"[Fix any problems that may 
exist]:emaint:((all\:'check all' world\:'check only world file'))"
+    "($sync_extra_opt $exclusive_cmd_opt)"{-c,--check}"[check for any problems 
that may exist]" \
+    "($fix_opt $purge_opt $sync_opt $sync_extra_opt $standalone_opt -t 
--time)"{-t,--time}"[(cleanlogs only)changes the minimum age NUM (in days) of 
the logs to be listed or deleted]" \
+    "($sync_extra_opt $exclusive_cmd_opt)"{-p,--pretend}"[output logs that 
would be deleted (cleanlogs only)]" \
+    "($fix_opt $sync_opt $sync_extra_opt $purge_opt)"{-C,--clean}"[cleans the 
logs from \$PORT_LOGDIR (cleanlogs only)]" \
+    "($log_extra_opt $sync_extra_opt $exclusive_cmd_opt 
$clean_opt)"{-P,--purge}"[removes the list of previously failed merges (merges 
only)]" \
+    "($repo_opt $log_extra_opt $exclusive_cmd_opt 
$clean_opt)"{-a,--auto}"[sync repositories which have their auto-sync setting 
set (sync module only)]" \
+    "($chk_opt $fix_opt $purge_opt $pretend_opt $log_extra_opt $clean_opt 
$standalone_opt)*"{-r,--repo}"=[Sync the specified repo]:gentoo repo:($repos)" \
+    "($repo_opt $log_extra_opt $exclusive_cmd_opt 
$clean_opt)"{-A,--allrepos}"[Sync all repos that have a sync-url defined (sync 
module only)]" \
+    "($chk_opt $fix_opt $purge_opt $pretend_opt $log_extra_opt $clean_opt 
$standalone_opt)*--sync-submodule=[restrict sync to the specified submodule 
(sync module only)]:portage submodule:(glsa news profiles)" \
+    "1:emaint commands:->emaint_cmd"
+
+  case $state in
+    (emaint_cmd)
+      local descr="emaint commands"
+
+      local cmd=(
+        'all:perform all supported commands that accept the specified option'
+        'logs:clean out old logs from the $PORT_LOGDIR'
+        'sync:perform sync actions on specified repositories'
+        'merges:scan for failed package merges and attempt to fix those failed 
packages'
+        'binhost:generate  a metadata index for binary packages located in 
$PKGDIR'
+        'cleanconfmem:discard no longer installed config tracker entries'
+        'cleanresume:discard merge lists saved for the emerge --resume action'
+        'movebin:perform package move updates for binary packages located in 
$PKGDIR'
+        'moveinst:perform package move updates for installed packages'
+        'world:fix problems in the world file'
+      )
+
+      local -a remove
+      if (( $words[(I)(-f|--fix)] )); then
+        remove=(${cmd[(r)logs:*]} ${cmd[(r)sync:*})
+      elif (( $words[(I)(-c|--check)] )); then
+        remove=(${cmd[(r)sync:*]})
+      elif (( $words[(I)(-p|--pretend|-C|--clean|-t|--time)] )); then
+        cmd=(${cmd[(r)logs:*]})
+      elif (( 
$words[(I)(-a|--auto|-A|--allrepos|-r=*|--repo=*|-r|--repo|--sync-submodule|--sync-submodule=*)]
 )); then
+        cmd=(${cmd[(r)sync:*]})
+      elif (( $words[(I)(--purge|-P)] )); then
+        cmd=(${cmd[(r)merges:*]})
+      else
+        remove=(${cmd[(r)sync:*]})
+      fi
+
+      cmd=(${cmd:|remove})
+      _describe $descr cmd
+
+      ;;
+  esac
 }
 
 _env-update () {

diff --git a/src/_portage_utils b/src/_portage_utils
index 4c41e16..9077f30 100644
--- a/src/_portage_utils
+++ b/src/_portage_utils
@@ -98,7 +98,7 @@ case $service in
       {'(--repo)-R','(-R)--repo'}'[Display installed packages with 
repository]' \
       {'(--umap)-U','(-U)--umap'}'[Display installed packages with flags 
used]' \
       {'(--columns)-c','(-c)--columns'}'[Display column view]' \
-      '--show-debug[Show /usr/lib/debug files]' \
+      '--show-debug[Show debug files]' \
       {'(--exact)-e','(-e)--exact'}'[Exact match (only CAT/PN or PN without 
PV)]' \
       {'(--all)-a','(-a)--all'}'[Show every installed package]' \
       {'(--dir)-d','(-d)--dir'}'[Only show directories]' \
@@ -115,7 +115,7 @@ case $service in
       {'(--unlist)-u','(-u)--unlist'}'[Show unmerge history]' \
       {'(--sync)-s','(-s)--sync'}'[Show sync history]' \
       {'(--current)-c','(-c)--current'}'[Show current emerging packages]' \
-      {'(--logfile)-f','(-f)--logfile'}'[Read emerge logfile instead of 
/var/log/emerge.log]:log:_files' \
+      {'(--logfile)-f','(-f)--logfile'}'[Read emerge logfile instead of 
$EMERGE_LOG_DIR/emerge.log]:log:_files' \
       '*:packages:_gentoo_packages available'
     ;;
   qsearch)

Reply via email to