[Bash-completion-commits] [SCM] bash-completion branch, use-_get_comp_words_by_ref, updated. bdca37a7bfdad428a072b71b7ec67b69bcc254a8

Freddy Vulto fvulto at gmail.com
Sun Mar 14 10:07:59 UTC 2010


The following commit has been merged in the use-_get_comp_words_by_ref branch:
commit bdca37a7bfdad428a072b71b7ec67b69bcc254a8
Author: Freddy Vulto <fvulto at gmail.com>
Date:   Sun Mar 14 11:07:13 2010 +0100

    Improve _get_comp_words_by_ref to return `words' and `cword'
    
    Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
    Available VARNAMES:
        cur         Return cur within varname "cur"
        prev        Return prev within varname "prev"
        words       Return words within varname "words"
        cword       Return cword within varname "cword"
    
    Available OPTIONS:
        -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT be
                    considered word breaks. This is useful for things like scp
                    where we want to return host:path and not only path, so we
                    would pass the colon (:) as -n option in this case.  Bash-3
                    doesn't do word splitting, so this ensures we get the same
                    word on both bash-3 and bash-4.
        -c VARNAME  Return cur within specified VARNAME
        -p VARNAME  Return prev within specified VARNAME
        -w VARNAME  Return words within specified VARNAME
        -i VARNAME  Return words within specified VARNAME
    
    Example usage:
    
       $ _get_comp_words_by_ref -n : cur prev

diff --git a/bash_completion b/bash_completion
index 9418aac..3948863 100644
--- a/bash_completion
+++ b/bash_completion
@@ -330,53 +330,83 @@ ___get_cword_at_cursor_by_ref() {
 # (For example, if the line is "ls foobar",
 # and the cursor is here -------->   ^
 # Also one is able to cross over possible wordbreak characters.
-# Usage: _get_comp_words_by_ref [OPTIONS] VAR1 [VAR2 [VAR3]]
+# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
+# Available VARNAMES:
+#     cur         Return cur within varname "cur"
+#     prev        Return prev within varname "prev"
+#     words       Return words within varname "words"
+#     cword       Return cword within varname "cword"
+#
+# Available OPTIONS:
+#     -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT be 
+#                 considered word breaks. This is useful for things like scp
+#                 where we want to return host:path and not only path, so we
+#                 would pass the colon (:) as -n option in this case.  Bash-3
+#                 doesn't do word splitting, so this ensures we get the same
+#                 word on both bash-3 and bash-4.
+#     -c VARNAME  Return cur within specified VARNAME
+#     -p VARNAME  Return prev within specified VARNAME
+#     -w VARNAME  Return words within specified VARNAME
+#     -i VARNAME  Return words within specified VARNAME
+#
 # Example usage:
 #
 #    $ _get_comp_words_by_ref -n : cur prev
 #
-# Options:  -n EXCLUDE  Characters out of $COMP_WORDBREAKS which should NOT
-#     be considered word breaks. This is useful for things like scp where
-#     we want to return host:path and not only path, so we would pass the
-#     colon (:) as -n option in this case.  Bash-3 doesn't do word splitting,
-#     so this ensures we get the same word on both bash-3 and bash-4.
 # @see __get_comp_words_by_ref
 _get_comp_words_by_ref() {
     # NOTE: The call to the main function __get_comp_words_by_ref() is wrapped
-    #       to make collisions with local variable name less likely.
-    local __words __cword __cur __var __vars 
-    __get_comp_words_by_ref __words __cword __cur __vars "$@"
-    set -- "${__vars[@]}"
-    eval $1=\$__cur
-    shift
-    for __var; do
-        ((__cword--))
-        [[ ${__words[__cword]} ]] && eval $__var=\${__words[__cword]}
-    done
+    #       to make collisions with local variable names less likely.
+    local __words __cword __cur
+    local __var_cur __var_prev __var_words __var_cword
+
+    __get_comp_words_by_ref \
+        __words __cword __cur \
+        __var_cur __var_prev __var_words __var_cword "$@"
+
+    [[ $__var_cur ]] && eval $__var_cur=\$__cur
+    [[ $__var_prev ]] && ((__cword)) && eval $__var_prev=\${__words[__cword - 1]}
+    [[ $__var_words ]] && eval $__var_words=\${__words[@]}
+    [[ $__var_cword ]] && eval $__var_cword=\$__cword
+    return 0
 }
 
 
-# @param $1 words  Name of variable to return words to
-# @param $2 cword  Name of variable to return cword to
-# @param $3 cur  Name of variable to return current word to complete to
-# @param $4 varnames  Name of variable to return array of variable names to
+# @param $1 words      Name of variable to return words to
+# @param $2 cword      Name of variable to return cword to
+# @param $3 cur        Name of variable to return current word to complete to
+# @param $4 var_cur    Name of variable to return current word to complete to
+# @param $5 var_prev   Name of variable to return previous word to complete to
+# @param $6 var_words  Name of variable to return words to complete to
+# @param $7 var_cword  Name of variable to return index of words to complete to
 # @param $@  Arguments to _get_comp_words_by_ref()
 # @note  Do not call this function directly but call `_get_comp_words_by_ref()'
 #     instead to make variable name collisions less likely
+#
 # @see _get_comp_words_by_ref()
 __get_comp_words_by_ref()
 {
-    local exclude flag i OPTIND=5  # Skip first four arguments
-    local cword words cur varnames=()
-    while getopts "n:" flag "$@"; do
+    local exclude flag i OPTIND=8  # Skip first seven arguments
+    local cword words cur
+    local var_cur var_cword var_prev var_words
+
+    while getopts "c:i:n:p:w:" flag "$@"; do
         case $flag in
+            c) var_cur=$OPTARG ;;
+            i) var_cword=$OPTARG ;;
             n) exclude=$OPTARG ;;
+            p) var_prev=$OPTARG ;;
+            w) var_words=$OPTARG ;;
         esac
     done
-    varnames=( ${!OPTIND} )
-    let "OPTIND += 1"
     while [[ $# -ge $OPTIND ]]; do 
-        varnames+=( ${!OPTIND} )
+        case ${!OPTIND} in
+            cur)   var_cur=cur ;;
+            prev)  var_prev=prev ;;
+            cword) var_cword=cword ;;
+            words) var_words=words ;;
+            *) echo "error: $FUNCNAME(): unknown argument: ${!OPTIND}"
+        esac
         let "OPTIND += 1"
     done
 
@@ -385,7 +415,10 @@ __get_comp_words_by_ref()
     eval $1=\( \"\${words[@]}\" \)
     eval $2=\$cword
     eval $3=\$cur
-    eval $4=\( \"\${varnames[@]}\" \)
+    eval $4=\$var_cur
+    eval $5=\$var_prev
+    eval $6=\${var_words[@]}
+    eval $7=\$var_cword
 }
 
 
diff --git a/test/unit/_get_comp_words_by_ref.exp b/test/unit/_get_comp_words_by_ref.exp
index 67862b3..1016d99 100644
--- a/test/unit/_get_comp_words_by_ref.exp
+++ b/test/unit/_get_comp_words_by_ref.exp
@@ -5,7 +5,10 @@ proc setup {} {
 
 
 proc teardown {} {
-    assert_bash_exec {unset COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS cur prev prev2}
+    assert_bash_exec { \
+        unset COMP_CWORD COMP_LINE COMP_POINT COMP_WORDS cur prev words cword \
+        cur2 prev2 words2 cword2 \
+    }
     # Delete 'COMP_WORDBREAKS' occupying two lines
     assert_env_unmodified {
         /COMP_WORDBREAKS=/{N
@@ -46,8 +49,8 @@ sync_after_int
 
 
 set test "a b |";  # | = cursor position
-set cmd {COMP_WORDS=(a b ''); COMP_CWORD=2; COMP_LINE='a b '; COMP_POINT=4; _get_comp_words_by_ref cur prev prev2; echo "$cur $prev $prev2"}
-assert_bash_list {" b a"} $cmd $test
+set cmd {COMP_WORDS=(a b ''); COMP_CWORD=2; COMP_LINE='a b '; COMP_POINT=4; _get_comp_words_by_ref cur prev; echo "$cur $prev"}
+assert_bash_list {" b"} $cmd $test
 
 
 sync_after_int
@@ -192,8 +195,8 @@ if {[lindex $::BASH_VERSINFO 0] <= 3} {
 }; # if
 append cmd {; COMP_LINE='a b c:'; COMP_POINT=6}
 assert_bash_exec $cmd $test
-set cmd {_get_comp_words_by_ref -n : cur prev; echo "$cur $prev $prev2"}
-assert_bash_list {"c: b a"} $cmd $test
+set cmd {_get_comp_words_by_ref -n : cur prev; echo "$cur $prev"}
+assert_bash_list {"c: b"} $cmd $test
 
 
 sync_after_int
@@ -336,4 +339,48 @@ expect {
 sync_after_int
 
 
+set test {unknown argument should raise error}
+set cmd {_get_comp_words_by_ref dummy}
+assert_bash_list {"error: __get_comp_words_by_ref(): unknown argument: dummy"} $cmd $test
+
+
+sync_after_int
+
+
+set test "a b| to all vars";  # | = cursor position
+set cmd {COMP_WORDS=(a b); COMP_CWORD=1; COMP_LINE='a b'; COMP_POINT=3}
+assert_bash_exec $cmd
+set cmd { \
+    _get_comp_words_by_ref words cword prev cur; echo "${words[@]} $cword $cur $prev" \
+}
+assert_bash_list {"a b 1 b a"} $cmd $test
+
+
+sync_after_int
+
+
+set test "a b| to alternate vars";  # | = cursor position
+set cmd {COMP_WORDS=(a b); COMP_CWORD=1; COMP_LINE='a b'; COMP_POINT=3;}
+assert_bash_exec $cmd
+set cmd {_get_comp_words_by_ref -c cur2 -p prev2 -w words2 -i cword2}
+assert_bash_exec $cmd
+set cmd {echo "$cur2 $prev2 ${words2[@]} $cword2"}
+assert_bash_list {"b a a b 1"} $cmd $test
+
+
+sync_after_int
+
+
+set test "a b| to alternate vars";  # | = cursor position
+set cmd {COMP_WORDS=(a b); COMP_CWORD=1; COMP_LINE='a b'; COMP_POINT=3;}
+assert_bash_exec $cmd
+set cmd {_get_comp_words_by_ref -c cur2 -p prev2 -w words2 -i cword2}
+assert_bash_exec $cmd
+set cmd {echo "$cur2 $prev2 ${words2[@]} $cword2"}
+assert_bash_list {"b a a b 1"} $cmd $test
+
+
+sync_after_int
+
+
 teardown

-- 
bash-completion



More information about the Bash-completion-commits mailing list