# [SCRIPT] zesearch un esearch en ZSH ;)

## Bapt

J'ai fait un petit script à la mano, encore plein de bugs, mais si il vous intéresse :

```

#Author: baptux <bapt@ifrance.com>

local trees category packages package var PORTDIR PORTDIR_OVERLAY name shortname

 version ebuild installed desc lic

for var in PORTDIR PORTDIR_OVERLAY ; do

        [[ -z ${(P)var} && -r /etc/make.conf ]] &&

                local $var="`. /etc/make.conf 2>/dev/null; echo ${(P)var}`"

        [[ -z ${(P)var} && -r /etc/make.globals ]] &&

                local $var="`. /etc/make.globals 2>/dev/null; echo ${(P)var}`"

done

trees=( $PORTDIR )

category=( $trees/*-*(/:t) )

packages=( $trees/*-*/* )

package=(${(M)packages:#/*/*/*-*/*$1*})

for pkg in $package; do

        name=(${${pkg#$PORTDIR/}%/})

        shortname=($pkg(:t))

        version=( $pkg/*.ebuild(:t) )

        version=(${${version#${shortname}-}%.ebuild})

        ebuilds=($pkg/*.ebuild)

        installed=( /var/db/pkg/$name-*(:t) )

        [[ "$installed" = "/var/db/pkg/$name-*(:t)" ]] && installed="[ Not insta

lled ]"

        installed=${installed#${shortname}-}

        for ebuild in $ebuilds;do

        done

        desc=`grep DESCRIPTION= $ebuild`

        desc=${${desc#DESCRIPTION=\"}%\"}

        lic=`grep LICENSE= $ebuild`

        lic=${${lic#LICENSE=\"}%\"}

        homepage=`grep HOMEPAGE= $ebuild`

        homepage=${${homepage#HOMEPAGE=\"}%\"}

        print "\033[1;32m * \033[1;0m$name"

        print "\t\033[2;32mAvailable versions: \033[1;0m$version"

        print "\t\033[2;32mInstalled: \033[1;0m$installed"

        print "\t\033[2;32mHomepage: \033[1;0m$homepage"

        print "\t\033[2;32mDescription: \033[1;0m$desc"

        print "\t\033[2;32mLicense: \033[1;0m$lic"

        print

done

```

pour l'essayer il faut le mettre dans un répertoire du fpath de zsh, puis 

```

autoload -U zesearch

zesearch xmms

```

Pour le moment il est un peu long à la première exécution, mais après il est rapide.

pas de cache a générer (avantage par rapport à esearch)

Il ne fait pas encore de recherche sur les description.

Il a un problème pour choper les informations inherit.

Je n'utilise pas le metadata car ils sont crades à parser (plein de ligne vides à la fin du fichier).

mais il marche  :Wink: ...

pour ceux qui n'utilise pas zsh et qui voudraient l'utiliser, ou ceux qui ne savent pas ce qu'est le fpath, il doit être possible de l'utiliser en mettant 

```
#!/bin/zsh
```

Au début du fichier et de coller le fichier avec les droits d'exécution dans un répertoire du path.

----------

## yoyo

 *baptux wrote:*   

> ceux qui ne savent pas ce qu'est le fpath

 Je suis de ces personnes ...   :Embarassed: 

Peux-tu expliquer où cela se configure / comment cela se configure ??

Merci.

PS : C'est toi qui est à l'origine de zsh-completion (l'ebuild présent dans portage) ??

----------

## TGL

 *baptux wrote:*   

> Je n'utilise pas le metadata car ils sont crades à parser (plein de ligne vides à la fin du fichier).

 

Nan, c'est tout bête à parser. Jette un oeil sur /usr/lib/portage/bin/ebuild.sh, tout à la fin du fichier (le cas "depend" dans le "case" principal), et tu auras la liste des noms de variables associés à chaque ligne. Les lignes blanches de la fin c'est de l'espace réservé pour en ajouter éventuellement plus un jour.

Je connais pas zsh, mais en bash en tout cas ça se parse vraiment en 3 lignes : 

```
#!/bin/bash

METADATA_VARS=" \

   DEPEND \

   RDEPEND \

   SLOT \

   SRC_URI \

   RESTRICT \

   HOMEPAGE \

   LICENSE \

   DESCRIPTION \

   KEYWORDS \

   INHERITED \

   IUSE \

   CDEPEND \

   PDEPEND \

   PROVIDE"

CACHE_DIR="/var/cache/edb/dep"

PORTDIR="$(/usr/lib/portage/bin/portageq envvar PORTDIR)"

parse_metadata() {

   local myvar

   for myvar in ${METADATA_VARS} ; do

      read ${myvar}

   done <${CACHE_DIR}${PORTDIR}/${1}

   # à adapter biensûr si tu veux aussi aller 

   # parser le/les overlay(s)

}

# test:

test_packages=" \

   sys-devel/gcc-3.4.3.20050110 \

   sys-kernel/gentoo-dev-sources-2.6.10-r6"

for mypkg in ${test_packages} ; do

   echo " * ${mypkg}:"

   parse_metadata ${mypkg}

   for myvar in ${METADATA_VARS} ; do

      echo -n "   ${myvar}: "

      eval echo "\${${myvar}}"

   done

   echo

done
```

 Par contre il faut bien avoir à l'esprit que le cache n'est pas en permanence 100% fiable. Enfin, il l'est en principe pour les paquets de l'arbre standard (si tu laisses le "emerge sync" le mettre à jour, ce qui est fait par défaut), mais pour les overlays il ne l'est pas tant que tu n'as pas utilisé un ebuild que tu aurais modifié. Mais bon, c'est pas forcement critique pour ton script.

----------

## yoyo

Ça marche pas ...    :Crying or Very sad: 

```
% zsh zesearch xmms   

zesearch:20: no matches found: /var/db/pkg/dev-python/pyxmms-*(:t)

zsh: exit 1     zsh zesearch xmms
```

Pour info : 

```
% emerge -vp pyxmms        

[ebuild  N    ] dev-python/pyxmms-2.02 
```

et

 *Quote:*   

> % ll /var/db/pkg/dev-python 
> 
> editobj-0.5.3
> 
> py2play-0.1.6
> ...

 

Une idée ???

----------

## Bapt

Yoyo : 

Oui je suis à l'origine de zsh-completions (loin d'être le seul, j'ai vite été aidé  :Wink: ) (d'ailleur une mise à jour conséquente devrait arriver bientôt : https://bugs.gentoo.org/show_bug.cgi?id=71957)

le fpath, il s'agit d'une variable d'environnement zsh (elle existe peut être dans d'autres shell) qui est l'ésuivalent du path mais pour les fonctions builtin zsh. Moi par exemple je met dans mes confs zsh : 

```

 fpath=($fpath $HOME/.zsh/function)

```

comme ça je met ma fonction zesearch (dans un fichier du même nom) par exemple dans le répertoire ~/.zsh/function, j'ai plus qu'à faire un :

```

autoload -U zesearch

```

pour qu'elle soit utilisable.

au lieu de faire ça, tu peux aussi copier le code dans ton fichier .zshrc de la manière suivante :

```

function zesearch () {

tu met ton code ici, et elle est automatiquement prise en compte.

}

```

le fpath est utilisé par zsh pour toutes les fonctions natives : completion, zmv, promptinit, mime-handler, zftp, tetris, etc.

YOYO : J'étais persuadé que ça fonctionnait en ligne avec zsh mais apparemment c'est uniquement utilisable en fonction built-in. (je viens de vérifier, ça ne fonctionne effectivement pas en ligne, mais uniquement en fonction)

Merci TGL pour l'information, je vais regarder si je ne peux pas utiliser directement les metadata.

----------

## yoyo

 *baptux wrote:*   

> le fpath est utilisé par zsh pour toutes les fonctions natives : completion, zmv, promptinit, mime-handler, zftp, tetris, etc.
> 
> YOYO : J'étais persuadé que ça fonctionnait en ligne avec zsh mais apparemment c'est uniquement utilisable en fonction built-in. (je viens de vérifier, ça ne fonctionne effectivement pas en ligne, mais uniquement en fonction)

 

Merci pour toutes ces explications baptux.   :Smile: 

J'ai cependant, toujours ce comportement bizarre :

```
zesearch portage                                             

 * app-portage/portage-manpages

        Available versions: 1.1

        Installed: 1.1

        Homepage: http://www.gentoo.org/

        Description: collection of Gentoo manpages

        License: GPL-2

zesearch:20: no matches found: /var/db/pkg/app-portage/portagemaster-*(:t)
```

  :Confused: 

----------

## Trevoke

[OFF] J'ai essaye zsh-completion et ca marche super, mais j'ai ete un peu ennuye par la facon dont ca marche, c'est-a-dire qu'on voit une completion par tab.. Je prefere la facon dont bash marche. Comment vous avez choisi cette methode ? (peut-etre que je ne vois juste pas la logique).

----------

## Bapt

C'est à dire une completion par tab ??, moi j'ai un menu déroulant en console, ça ne dépend pas de nous, mais de la conf de ta completion, chez moi :

```

# list of completers to use

zstyle ':completion:*::::' completer _expand _complete _ignored _approximate

# allow one error for every three characters typed in approximate completer

zstyle -e ':completion:*:approximate:*' max-errors \

    'reply=( $(( ($#PREFIX+$#SUFFIX)/3 )) numeric )'

# insert all expansions for expand completer

zstyle ':completion:*:expand:*' tag-order all-expansions

# formatting and messages

zstyle ':completion:*' verbose yes

zstyle ':completion:*:descriptions' format "$user_color%B%d%b$end"

zstyle ':completion:*:messages' format '%d'

zstyle ':completion:*:warnings' format "${root_color}Rien ne correspond dans: %d$end"

zstyle ':completion:*:corrections' format "$user_color%B%d (erreurs: %e)%b$end"

zstyle ':completion:*' group-name ''

# match uppercase from lowercase

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=* l:|=*'

# offer indexes before parameters in subscripts

zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters

zstyle ':completion:*' menu select=2

zstyle ':completion:*' select-prompt %SScrolling active: current selection at %p%s

zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}

zstyle ':completion:*' list-prompt %SAt %p: Hit TAB for more, or the character to insert%s

```

Voila ce qui régit ma completion, + deux ou trois trucs  :Wink: 

----------

## Trevoke

Et c'est quoi ce fichier de configuration?

----------

## Bapt

 *yoyo wrote:*   

> 
> 
> J'ai cependant, toujours ce comportement bizarre :
> 
> ```
> ...

 

C'est un beau bug  :Wink: . Je vais essayer de le refaire en utilisant les metadata ce WE, et en virant ce bug. Il faut que je le rendre plus rapide.

PS : un tip zsh : pour accélerer zsh et son démarrage, il est possible de compiler les fonctions et fichier de conf zsh : 

```
zrecompile -p ~/.zshrc
```

par exemple  :Wink: 

----------

## Bapt

 *Trevoke wrote:*   

> Et c'est quoi ce fichier de configuration?

 

C'est dans mon .zshrc (ou plutôt chez moi dans mon .zshcomplete qui est lu par le .zshrc)

mais je metterais mes confs en lignes Lundi (Un peu de nettoyage pour que ce ne soit pas trop crade quand même  :Wink: )

----------

## Bapt

Ma conf zsh pour ceux que ça intéresse (zesearch est inclus): 

http://baptux.free.fr/zsh-conf-2005-01-21.tar.gz

Une mise à jour de zesearch utilisant les metadata (merci TGL  :Wink: ) et avec -s quelquecchose pour chercher dans les descriptions (mais c'est très lent) :

```

#Author: baptux <bapt@ifrance.com>

#

#Thanks for the help of TGL

#TODO:  Make it work with portage overlay

local trees var PORTDIR PORTDIR_OVERLAY packages package METADATA_VARS pkg CACHE_DIR DESCRIPTION RESTRICT SLOT SRC_URI HOMEPAGE LICENSE INHERITED IUSE CDEPEND PROVIDE PDEPEND RDEPEND KEYWORDS DEPEND name myvar installed versions namelist

METADATA_VARS=(DEPEND \

RDEPEND \

SLOT \

SRC_URI \

RESTRICT \

HOMEPAGE \

LICENSE \

DESCRIPTION \

KEYWORDS \

INHERITED \

IUSE \

CDEPEND \

PDEPEND \

PROVIDE)

for var in PORTDIR PORTDIR_OVERLAY ; do

   [[ -z ${(P)var} && -r /etc/make.conf ]] &&

      local $var="`. /etc/make.conf 2>/dev/null; echo ${(P)var}`"

   [[ -z ${(P)var} && -r /etc/make.globals ]] &&

      local $var="`. /etc/make.globals 2>/dev/null; echo ${(P)var}`"

done

function search_desc () {

   print "\033[1;31mResults for $1 in descriptions:"

   CACHE_DIR="/var/cache/edb/dep"

   trees=( $PORTDIR )

   #List all available ebuild

   packages=( ${CACHE_DIR}${trees}/*-*/* )

   #Get Unique package

   packages=(${(u)${packages%-[0-9]*}})

   for package in $packages;do   

      name=(${package#$CACHE_DIR$PORTDIR/})

      namelist=( ${package}-[0-9]* )

      for myvar in $METADATA_VARS;do 

         read ${myvar}

      done <$namelist[0]

      desc=${(M)DESCRIPTION:#*$1*}

      if [ "$desc" != "" ];then 

         versions=${namelist#$CACHE_DIR$PORTDIR/${name}-}

         installed=( /var/db/pkg/$name-[0-9]* )

         [[ "$installed" = "/var/db/pkg/$name-[0-9]*" ]] && installed="[ Not installed ]"

         print "\033[1;32m * \033[1;37m$name"

         print "\t\033[0;32mAvailable versions: \033[1;0m$versions"

         print "\t\033[0;32mInstalled: \033[1;0m$installed"

         print "\t\033[0;32mHomepage: \033[1;0m$HOMEPAGE"

         print "\t\033[0;32mDescription: \033[1;0m$DESCRIPTION"

         print "\t\033[0;32mLicense: \033[1;0m$LICENSE"

         print

      fi

   done

}

function search_ebuild () {

   print "\033[1;31mResults for $1:"

   CACHE_DIR="/var/cache/edb/dep"

   trees=( $PORTDIR )

   #List all packages

   packages=( ${CACHE_DIR}${trees}/*-*/* )

   #get unique of each

   packages=(${(u)${${(M)packages:#$CACHE_DIR$PORTDIR/*-*/*$1*}%-[0-9]*}})

   for package in $packages; do

      name=(${package#$CACHE_DIR$PORTDIR/})

      namelist=($package-[0-9]*)

      for myvar in $METADATA_VARS;do 

         read ${myvar}

      done <$namelist[0]

      versions=${namelist#$CACHE_DIR$PORTDIR/${name}-}

      installed=( /var/db/pkg/$name-[0-9]* )

      [[ "$installed" = "/var/db/pkg/$name-[0-9]*" ]] && installed="[ Not installed ]"

      installed=${${installed#/var/db/pkg/$name-}%/}

      print "\033[1;32m * \033[1;37m$name"

      print "\t\033[0;32mAvailable versions: \033[1;0m$versions"

      print "\t\033[0;32mInstalled: \033[1;0m$installed"

      print "\t\033[0;32mHomepage: \033[1;0m$HOMEPAGE"

      print "\t\033[0;32mDescription: \033[1;0m$DESCRIPTION"

      print "\t\033[0;32mLicense: \033[1;0m$LICENSE"

      print

   done

}

[[ "$#" = "0" ]] && print "zesearch [pattern]"

case $1 in

   -s)

      search_desc $2

   ;;

   *)

      for pattern in $@;do

         search_ebuild $pattern

      done

   ;;

esac

```

----------

