219 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| # ghc-pkg command line completion for bash
 | |
| #
 | |
| # Copyright 2006-2007 Lennart Kolmodin <kolmodin@dtek.chalmers.se>
 | |
| 
 | |
| _ghc-pkg-get-ghc-pkg()
 | |
| {
 | |
|     echo ghc-pkg
 | |
| }
 | |
| 
 | |
| _ghc-pkg-pkg-fields()
 | |
| {
 | |
|     # usage: _ghc-pkg-pkg-fields pkg-id
 | |
|     #
 | |
|     # list all fields of the pkg-id
 | |
| 
 | |
|     # same fields for all packages but different in different versions of
 | |
|     # ghc-pkg? this can probably be done better/faster
 | |
| 
 | |
|     if [[ -z "$1" ]]; then
 | |
|         echo "usage: _ghc-pkg-pkg-fields pkg-id"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     local fields
 | |
| 
 | |
|     fields="$( $(_ghc-pkg-get-ghc-pkg) describe $1 )"
 | |
| 
 | |
|     #if [[ fields != *"cannot find package"* ]]; then
 | |
|     echo "$fields" | grep ".*:.*" | sed "s/^\(.*\):.*\$/\1/"
 | |
|     #fi
 | |
| }
 | |
| 
 | |
| _ghc-pkg-pkg-ids()
 | |
| {
 | |
|     # usage: _ghc-pkg-pkg-ids
 | |
|     #
 | |
|     # simply lists all package ids known by ghc-pkg.
 | |
|     $(_ghc-pkg-get-ghc-pkg) list --simple-output
 | |
| }
 | |
| 
 | |
| _ghc-pkg-pkgs()
 | |
| {
 | |
|     # usage: _ghc-pkg-pkgs [include-pkgs] [include-ids]
 | |
|     #
 | |
|     # with optional parameter include-pkgs it will list all packages known
 | |
|     # to ghc-pkg.
 | |
|     # with optional parameter include-ids it will list all package-ids known
 | |
|     # to ghc-pkg.
 | |
|     local pkgs
 | |
|     local result
 | |
|     pkgs=( $( _ghc-pkg-pkg-ids ) )
 | |
|     result=( )
 | |
| 
 | |
|     local withPkgs="no" withIds="no"
 | |
|     while [[ -n "$1" ]]; do
 | |
|         case "$1" in
 | |
|             include-pkgs)
 | |
|                 withPkgs="yes" ;;
 | |
|             include-ids)
 | |
|                 withIds="yes" ;;
 | |
|             *)
 | |
|                 echo "unknown parameter '$1' to _ghc-pkg-pkgs"
 | |
|                 return 1 ;;
 | |
|         esac
 | |
|         shift
 | |
|     done
 | |
| 
 | |
|     # user must supply either include-pkgs, include-ids or both
 | |
|     if [[ $withPkgs != "yes" && $withIds != "yes" ]]; then
 | |
|         echo "usage: _ghc-pkg-pkgs [include-pkgs] [include-ids]"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # find all packages if the user requested them
 | |
|     if [[ $withPkgs == "yes" ]]; then
 | |
|         # O(n^2) algorithm to exclude duplicates
 | |
|         for p in ${pkgs[*]}; do
 | |
|             p="${p//-[0-9.]*/}"
 | |
|             for existing in ${result[*]}; do
 | |
|                 if [[ "$existing" == "$p" ]]; then
 | |
|                     continue 2
 | |
|                 fi
 | |
|             done
 | |
|             result=( "${result[@]}" "${p}" )
 | |
|         done
 | |
|     fi
 | |
| 
 | |
|     # include all pkg-ids if requested
 | |
|     if [[ $withIds == "yes" ]]; then
 | |
|         result=( "${result[@]}" "${pkgs[@]}" )
 | |
|     fi
 | |
| 
 | |
|     # we are finished, echo the result
 | |
|     echo "${result[*]}"
 | |
| 
 | |
|     # happy ending
 | |
|     return 0
 | |
| }
 | |
| 
 | |
| _ghc-pkg()
 | |
| {
 | |
|     local cur
 | |
|     cur=${COMP_WORDS[COMP_CWORD]}
 | |
| 
 | |
|     COMPREPLY=()
 | |
| 
 | |
|     local actions flags
 | |
|     actions='register update unregister expose hide list latest describe field'
 | |
|     dbflags="--user \
 | |
|         --global \
 | |
|         -f --package-conf= \
 | |
|         --global-conf="
 | |
|     registerflags="--force \
 | |
|         -g --auto-ghci-libs \
 | |
|         -D --define-name="
 | |
|     listflags="--simple-output"
 | |
|     flags="$dbflags \
 | |
|         $registerflags \
 | |
|         $listflags \
 | |
|         -? --help \
 | |
|         -V --version"
 | |
| 
 | |
|     # if it's the users first word; complete it and return
 | |
|     if (($COMP_CWORD == 1)); then
 | |
|         COMPREPLY=( $( compgen -W "$actions $flags" -- $cur ) )
 | |
|         return 0
 | |
|     fi
 | |
| 
 | |
|     # now we know we have at least one word written
 | |
| 
 | |
|     local action="unknown" \
 | |
|           prev numwords \
 | |
|           cword act
 | |
|     prev=${COMP_WORDS[COMP_CWORD-1]}
 | |
|     numwords=${#COMP_WORDS[@]}
 | |
| 
 | |
|     # find the action with O(n*m) algorithm
 | |
|     # where n = ${#COMP_WORDS[*]}
 | |
|     #       m = number of actions
 | |
|     for cword in ${COMP_WORDS[*]}; do
 | |
|         for act in $actions; do
 | |
|             if [[ "$cword" == "$act" ]]; then
 | |
|                 action=$cword
 | |
|             fi
 | |
|         done
 | |
|     done
 | |
| 
 | |
|     case $action in
 | |
|         register|update)
 | |
|             # we want to complete both flags and paths, how?
 | |
|             # we do it by checking if the user has started to write a flag
 | |
|             # or a path, and then decide what to complete.
 | |
|             # that is, to complete a flag, the user must start to write a '-'
 | |
|             if [[ "$cur" == -* ]]; then
 | |
|                 # (we assume) it's the start of a flag
 | |
|                 # set COMPREPLY to flags relevant to these actions
 | |
|                 COMPREPLY=( $( compgen -W "$dbflags $registerflags" -- $cur ) )
 | |
|             fi
 | |
|             ;;
 | |
|         unregister|expose|hide|list|describe)
 | |
|             # all these actions can be completed with exactly one argument,
 | |
|             # a pkg-id.
 | |
|             COMPREPLY=( $( compgen -W "$dbflags" -- $cur ) )
 | |
| 
 | |
|             # add special flags for some actions
 | |
|             if [[ "$action" == "list" ]]; then
 | |
|                 COMPREPLY+=( $( compgen -W "$listflags" -- $cur ) )
 | |
|             fi
 | |
| 
 | |
|             COMPREPLY+=( $( compgen -W "$( _ghc-pkg-pkgs include-ids )" -- $cur ) )
 | |
|             ;;
 | |
|         latest)
 | |
|             # complete only packages, not package ids
 | |
|             COMPREPLY=( $( compgen -W "$( _ghc-pkg-pkgs include-pkgs )" -- $cur ) )
 | |
|             ;;
 | |
|         field)
 | |
|             # we should always complete on the flags...
 | |
|             COMPREPLY=( $( compgen -W "$dbflags" -- $cur ) )
 | |
| 
 | |
|             # then, we should either complete the package name or the field
 | |
|             # lets find out which one
 | |
| 
 | |
|             # find the number of words in COMP_WORDS before COMP_CWORD that
 | |
|             # isn't flags. it should be 2 or 3 for us to complete it,
 | |
|             #   exactly 2 if we should complete the package name
 | |
|             #   exactly 3 if we should complete the field name
 | |
|             #   otherwise, don't do any additional completion except the
 | |
|             #   flags
 | |
| 
 | |
|             # count the number of non flags up till the current word
 | |
|             local numnonflags=0 lastword i
 | |
|             for (( i=0 ; $i < $COMP_CWORD ; i++ )); do
 | |
|                 if [[ ${COMP_WORDS[$i]} != -* ]]; then
 | |
|                     lastword=${COMP_WORDS[$i]}
 | |
|                     numnonflags=$(( ++numnonflags ))
 | |
|                 fi
 | |
|             done
 | |
| 
 | |
|             case $numnonflags in
 | |
|                 2)
 | |
|                     # complete on pkg-ids
 | |
|                     COMPREPLY+=( $( compgen -W "$( _ghc-pkg-pkgs include-ids )" -- $cur ) ) ;;
 | |
|                 3)
 | |
|                     # complete on fields
 | |
|                     COMPREPLY+=( $( compgen -W "$( _ghc-pkg-pkg-fields $lastword )" -- $cur ) ) ;;
 | |
|             esac
 | |
|             ;;
 | |
|         *)
 | |
|             # unknown action, not yet given by the user
 | |
|             # return all possible completions
 | |
|             COMPREPLY=( $( compgen -W "$actions $flags" -- $cur ) )
 | |
|             ;;
 | |
|     esac
 | |
| }
 | |
| 
 | |
| complete -F _ghc-pkg -o default ghc-pkg
 | |
| 
 | |
| # vim: set ft=sh tw=80 sw=4 et :
 |