ghc-bash-completion 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. # ghc-pkg command line completion for bash
  2. #
  3. # Copyright 2006-2007 Lennart Kolmodin <kolmodin@dtek.chalmers.se>
  4. _ghc-pkg-get-ghc-pkg()
  5. {
  6. echo ghc-pkg
  7. }
  8. _ghc-pkg-pkg-fields()
  9. {
  10. # usage: _ghc-pkg-pkg-fields pkg-id
  11. #
  12. # list all fields of the pkg-id
  13. # same fields for all packages but different in different versions of
  14. # ghc-pkg? this can probably be done better/faster
  15. if [[ -z "$1" ]]; then
  16. echo "usage: _ghc-pkg-pkg-fields pkg-id"
  17. return 1
  18. fi
  19. local fields
  20. fields="$( $(_ghc-pkg-get-ghc-pkg) describe $1 )"
  21. #if [[ fields != *"cannot find package"* ]]; then
  22. echo "$fields" | grep ".*:.*" | sed "s/^\(.*\):.*\$/\1/"
  23. #fi
  24. }
  25. _ghc-pkg-pkg-ids()
  26. {
  27. # usage: _ghc-pkg-pkg-ids
  28. #
  29. # simply lists all package ids known by ghc-pkg.
  30. $(_ghc-pkg-get-ghc-pkg) list --simple-output
  31. }
  32. _ghc-pkg-pkgs()
  33. {
  34. # usage: _ghc-pkg-pkgs [include-pkgs] [include-ids]
  35. #
  36. # with optional parameter include-pkgs it will list all packages known
  37. # to ghc-pkg.
  38. # with optional parameter include-ids it will list all package-ids known
  39. # to ghc-pkg.
  40. local pkgs
  41. local result
  42. pkgs=( $( _ghc-pkg-pkg-ids ) )
  43. result=( )
  44. local withPkgs="no" withIds="no"
  45. while [[ -n "$1" ]]; do
  46. case "$1" in
  47. include-pkgs)
  48. withPkgs="yes" ;;
  49. include-ids)
  50. withIds="yes" ;;
  51. *)
  52. echo "unknown parameter '$1' to _ghc-pkg-pkgs"
  53. return 1 ;;
  54. esac
  55. shift
  56. done
  57. # user must supply either include-pkgs, include-ids or both
  58. if [[ $withPkgs != "yes" && $withIds != "yes" ]]; then
  59. echo "usage: _ghc-pkg-pkgs [include-pkgs] [include-ids]"
  60. return 1
  61. fi
  62. # find all packages if the user requested them
  63. if [[ $withPkgs == "yes" ]]; then
  64. # O(n^2) algorithm to exclude duplicates
  65. for p in ${pkgs[*]}; do
  66. p="${p//-[0-9.]*/}"
  67. for existing in ${result[*]}; do
  68. if [[ "$existing" == "$p" ]]; then
  69. continue 2
  70. fi
  71. done
  72. result=( "${result[@]}" "${p}" )
  73. done
  74. fi
  75. # include all pkg-ids if requested
  76. if [[ $withIds == "yes" ]]; then
  77. result=( "${result[@]}" "${pkgs[@]}" )
  78. fi
  79. # we are finished, echo the result
  80. echo "${result[*]}"
  81. # happy ending
  82. return 0
  83. }
  84. _ghc-pkg()
  85. {
  86. local cur
  87. cur=${COMP_WORDS[COMP_CWORD]}
  88. COMPREPLY=()
  89. local actions flags
  90. actions='register update unregister expose hide list latest describe field'
  91. dbflags="--user \
  92. --global \
  93. -f --package-conf= \
  94. --global-conf="
  95. registerflags="--force \
  96. -g --auto-ghci-libs \
  97. -D --define-name="
  98. listflags="--simple-output"
  99. flags="$dbflags \
  100. $registerflags \
  101. $listflags \
  102. -? --help \
  103. -V --version"
  104. # if it's the users first word; complete it and return
  105. if (($COMP_CWORD == 1)); then
  106. COMPREPLY=( $( compgen -W "$actions $flags" -- $cur ) )
  107. return 0
  108. fi
  109. # now we know we have at least one word written
  110. local action="unknown" \
  111. prev numwords \
  112. cword act
  113. prev=${COMP_WORDS[COMP_CWORD-1]}
  114. numwords=${#COMP_WORDS[@]}
  115. # find the action with O(n*m) algorithm
  116. # where n = ${#COMP_WORDS[*]}
  117. # m = number of actions
  118. for cword in ${COMP_WORDS[*]}; do
  119. for act in $actions; do
  120. if [[ "$cword" == "$act" ]]; then
  121. action=$cword
  122. fi
  123. done
  124. done
  125. case $action in
  126. register|update)
  127. # we want to complete both flags and paths, how?
  128. # we do it by checking if the user has started to write a flag
  129. # or a path, and then decide what to complete.
  130. # that is, to complete a flag, the user must start to write a '-'
  131. if [[ "$cur" == -* ]]; then
  132. # (we assume) it's the start of a flag
  133. # set COMPREPLY to flags relevant to these actions
  134. COMPREPLY=( $( compgen -W "$dbflags $registerflags" -- $cur ) )
  135. fi
  136. ;;
  137. unregister|expose|hide|list|describe)
  138. # all these actions can be completed with exactly one argument,
  139. # a pkg-id.
  140. COMPREPLY=( $( compgen -W "$dbflags" -- $cur ) )
  141. # add special flags for some actions
  142. if [[ "$action" == "list" ]]; then
  143. COMPREPLY+=( $( compgen -W "$listflags" -- $cur ) )
  144. fi
  145. COMPREPLY+=( $( compgen -W "$( _ghc-pkg-pkgs include-ids )" -- $cur ) )
  146. ;;
  147. latest)
  148. # complete only packages, not package ids
  149. COMPREPLY=( $( compgen -W "$( _ghc-pkg-pkgs include-pkgs )" -- $cur ) )
  150. ;;
  151. field)
  152. # we should always complete on the flags...
  153. COMPREPLY=( $( compgen -W "$dbflags" -- $cur ) )
  154. # then, we should either complete the package name or the field
  155. # lets find out which one
  156. # find the number of words in COMP_WORDS before COMP_CWORD that
  157. # isn't flags. it should be 2 or 3 for us to complete it,
  158. # exactly 2 if we should complete the package name
  159. # exactly 3 if we should complete the field name
  160. # otherwise, don't do any additional completion except the
  161. # flags
  162. # count the number of non flags up till the current word
  163. local numnonflags=0 lastword i
  164. for (( i=0 ; $i < $COMP_CWORD ; i++ )); do
  165. if [[ ${COMP_WORDS[$i]} != -* ]]; then
  166. lastword=${COMP_WORDS[$i]}
  167. numnonflags=$(( ++numnonflags ))
  168. fi
  169. done
  170. case $numnonflags in
  171. 2)
  172. # complete on pkg-ids
  173. COMPREPLY+=( $( compgen -W "$( _ghc-pkg-pkgs include-ids )" -- $cur ) ) ;;
  174. 3)
  175. # complete on fields
  176. COMPREPLY+=( $( compgen -W "$( _ghc-pkg-pkg-fields $lastword )" -- $cur ) ) ;;
  177. esac
  178. ;;
  179. *)
  180. # unknown action, not yet given by the user
  181. # return all possible completions
  182. COMPREPLY=( $( compgen -W "$actions $flags" -- $cur ) )
  183. ;;
  184. esac
  185. }
  186. complete -F _ghc-pkg -o default ghc-pkg
  187. # vim: set ft=sh tw=80 sw=4 et :