Repository : ssh://darcs.haskell.org//srv/darcs/packages/Cabal

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/23b7a2fcb3518b7bac529a7dedfcc6e63a949e33

>---------------------------------------------------------------

commit 23b7a2fcb3518b7bac529a7dedfcc6e63a949e33
Author: Lennart Kolmodin <[email protected]>
Date:   Mon Mar 3 18:32:31 2008 +0000

    CLI completion: Add completion of packages
    Add completion of packages to the commands install, list, upgrade and fetch.
    Only complete packages if the user is not trying to complete a flag.
    Complete with package-versions if the package name ends with a dash,
    otherwise just complete with the package names.

>---------------------------------------------------------------

 cabal-install/bash-completion/cabal |  115 ++++++++++++++++++++++++++++++++--
 1 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/cabal-install/bash-completion/cabal 
b/cabal-install/bash-completion/cabal
index 0beccee..1f0a563 100644
--- a/cabal-install/bash-completion/cabal
+++ b/cabal-install/bash-completion/cabal
@@ -1,8 +1,72 @@
 # cabal command line completion
-# Copyright 2007 "Lennart Kolmodin" <[email protected]>
-#                "Duncan Coutts"     <[email protected]>
+# Copyright 2007-2008 "Lennart Kolmodin" <[email protected]>
+#                     "Duncan Coutts"     <[email protected]>
 #
 
+# returns packages from cabal list
+# usage: _cabal_packages [packages] [versions] [installed]
+_cabal_packages()
+{
+    local packages=no # print package names with versions? ie. foo
+    local versions=no # print packages and versions? ie. foo-0.42
+    local installed=no # only print installed packages?
+
+    while [[ -n "$1" ]]; do
+        case "$1" in
+            packages)
+                packages=yes ;;
+            versions)
+                versions=yes ;;
+            installed)
+                installed=yes ;;
+        esac
+        shift
+    done
+
+    if [[ "$packages" == "no" && "$versions" == "no" ]]; then
+        # nothing to print
+        # set sensible default, print only packages
+        packages=yes
+    fi
+
+    local cmd="cabal list --simple-output"
+    if [[ "$installed" == "yes" ]]; then
+        cmd="$cmd --installed"
+    fi
+
+    # save 'cabal list' output to a temporary file
+    # putting it in a variable would mess up the lines
+    local tmp=$( mktemp /tmp/cabal_completion.XXXXXX )
+    $cmd > $tmp
+
+    if [[ "$packages" == "yes" ]]; then
+        # print only the names
+        cat "$tmp" | cut -d' ' -f1 | uniq
+    fi
+
+    if [[ "$versions" == "yes" ]]; then
+        # join the name and the version with a dash
+        cat "$tmp" | sed -e "s: :-:"
+    fi
+
+    rm -f "$tmp"
+}
+
+_cabal_commands()
+{
+    # this is already quite fast, and caching does not give a speedup
+    # 3-4ms
+    for word in $( cabal --list-options ); do
+        case $word in
+            -*)
+                # ignore flags
+                continue;;
+            *)
+                echo $word ;;
+        esac
+    done
+}
+
 _cabal()
 {
     # get the word currently being completed
@@ -14,17 +78,54 @@ _cabal()
     # copy all words the user has entered
     cmd=( ${COMP_WORDS[@]} )
 
+    # the word currently beeing completed
+    local ccword
+    ccword=cmd[${COMP_CWORD}]
+
     # replace the current word with --list-options
     cmd[${COMP_CWORD}]="--list-options"
 
-    # TODO: add completion of packages
-    # we want cabal support for this to make it fast
-    # $ time cabal list | cut -d' ' -f1
-    # real    0m2.454s
-    # on a Intel Core 2 Duo 1.6 GHz, too slow
+    # find the action being completed
+    local action="unknown"
+    for cword in ${COMP_WORDS[*]}; do
+        for act in $( _cabal_commands ); do
+            if [[ "$cword" == "$act" ]]; then
+                action=$act
+            fi
+        done
+    done
+
+    # if non empty, we will pass this to _cabal_packages and add the result
+    # to the completing words
+    local complete_packages
+    for cword in ${COMP_WORDS[*]}; do
+        case $cword in
+            --installed)
+                # the user is interested only in installed packages
+                complete_packages="$complete_packages installed"
+        esac
+    done
+
+    case $action in
+        install|list|upgrade|fetch)
+            if [[ "$cword" != -* ]]; then
+                # don't complete with packages if the user is trying to
+                # complete a flag
+                complete_packages="$complete_packages packages"
+                if [[ "$cword" == *- ]]; then
+                    # if the user tries to complete with a version, help by
+                    # completing them too
+                    complete_packages="$complete_packages versions"
+                fi
+            fi ;;
+    esac
 
     # the resulting completions should be put into this array
     COMPREPLY=( $( compgen -W "$( ${cmd[@]} )" -- $cur ) )
+
+    if [[ -n "$complete_packages" ]]; then
+        COMPREPLY+=( $( compgen -W "$( _cabal_packages $complete_packages )" 
-- $cur ) )
+    fi
 }
 
 complete -F _cabal -o default cabal



_______________________________________________
Cvs-libraries mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-libraries

Reply via email to