[Bash-completion-commits] [SCM] bash-completion branch, master, updated. 1.3-40-g8227e76

Freddy Vulto fvulto at gmail.com
Wed Mar 23 23:01:42 UTC 2011


The following commit has been merged in the master branch:
commit 8227e76e09fc4bdd21a6e0bf866445910f64815e
Author: Freddy Vulto <fvulto at gmail.com>
Date:   Thu Mar 24 00:00:58 2011 +0100

    Improve __reassemble_comp_words_by_ref() (Alioth #313057)
    Prohibit word creation of characters if they're excluded from
    $COMP_WORDBREAKS.  For example, with ':' included in $COMP_WORDBREAKS,
    'a b:' should split to 'b' and ':'.  With ':' excluded from
    $COMP_WORDBREAKS, 'a b:' should split to 'b:', NOT 'b' and ':'.

diff --git a/CHANGES b/CHANGES
index 8240aec..679fae3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -14,6 +14,10 @@ bash-completion (2.x)
   * If _filedir 'ext' returns nothing, just fallback to generic
     file completion. Patch by Clint Byrum (Debian: #619014, LP: #533985)
 
+  [ Freddy Vulto ]
+  * Improve __reassemble_comp_words_by_ref() to not create words of
+    characters-to-exclude (Alioth: #313057)
+
  -- David Paleino <d.paleino at gmail.com>  Sun, 06 Feb 2011 21:46:37 +0100
 
 bash-completion (1.3)
diff --git a/bash_completion b/bash_completion
index 4fc5035..dd61e9d 100644
--- a/bash_completion
+++ b/bash_completion
@@ -277,7 +277,7 @@ _upvars() {
 # @param $3 cword  Name of variable to return cword to
 #
 __reassemble_comp_words_by_ref() {
-    local exclude i j ref
+    local exclude i j line ref
     # Exclude word separator characters?
     if [[ $1 ]]; then
         # Yes, exclude word separator characters;
@@ -290,26 +290,40 @@ __reassemble_comp_words_by_ref() {
     # Are characters excluded which were former included?
     if [[ $exclude ]]; then
         # Yes, list of word completion separators has shrunk;
+        line=$COMP_LINE
         # Re-assemble words to complete
         for (( i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
             # Is current word not word 0 (the command itself) and is word not
-            # empty and is word made up of just word separator characters to be
-            # excluded?
+            # empty and is word made up of just word separator characters to
+            # be excluded and is current word not preceded by whitespace in
+            # original line?
             while [[ $i -gt 0 && ${COMP_WORDS[$i]} && 
-                ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]} 
+                ${COMP_WORDS[$i]//[^$exclude]} == ${COMP_WORDS[$i]}
             ]]; do
-                [ $j -ge 2 ] && ((j--))
-                # Append word separator to current word
+                # Is word separator not preceded by whitespace in original line
+                # and are we not going to append to word 0 (the command
+                # itself), then append to current word.
+                [[ ${line:0:1} != ' ' && ${line:0:1} != $'\t' ]] &&
+                    (( j >= 2 )) && ((j--))
+                # Append word separator to current or new word
                 ref="$2[$j]"
                 eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
                 # Indicate new cword
                 [ $i = $COMP_CWORD ] && eval $3=$j
-                # Indicate next word if available, else end *both* while and for loop
+                # Remove whitespace (optional) + word separator from line copy
+                line=${line#*${COMP_WORDS[$i]}}
+                # Start new word if word separator in original line is
+                # followed by whitespace.
+                [[ ${line:0:1} == ' ' || ${line:0:1} == $'\t' ]] && ((j++))
+                # Indicate next word if available, else end *both* while and
+                # for loop
                 (( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
             done
             # Append word to current word
             ref="$2[$j]"
             eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+            # Remove whitespace (optional) + word from line copy
+            line=${line#*${COMP_WORDS[i]}}
             # Indicate new cword
             [[ $i == $COMP_CWORD ]] && eval $3=$j
         done
diff --git a/test/unit/_get_comp_words_by_ref.exp b/test/unit/_get_comp_words_by_ref.exp
index 2ddcef2..2aa0ae9 100644
--- a/test/unit/_get_comp_words_by_ref.exp
+++ b/test/unit/_get_comp_words_by_ref.exp
@@ -398,4 +398,44 @@ assert_bash_list {"b a a b 1"} $cmd $test
 sync_after_int
 
 
+set test {a b : c| with WORDBREAKS -= :};  # | = cursor position
+set cmd {COMP_WORDS=(a b : c); COMP_CWORD=3; COMP_LINE='a b : c'; COMP_POINT=7}
+assert_bash_exec $cmd $test
+set cmd {_get_comp_words_by_ref -n : words; echo "${words[@]}"}
+assert_bash_list {"a b : c"} $cmd $test
+
+
+sync_after_int
+
+
+set test {a b: c| with WORDBREAKS -= :};  # | = cursor position
+if {[lindex $::BASH_VERSINFO 0] <= 3} {
+    set cmd {COMP_WORDS=(a b: c); COMP_CWORD=2}
+} else {
+    set cmd {COMP_WORDS=(a b : c); COMP_CWORD=3}
+}
+append cmd {; COMP_LINE='a b: c'; COMP_POINT=6}
+assert_bash_exec $cmd $test
+set cmd {_get_comp_words_by_ref -n : words; echo "${words[@]}"}
+assert_bash_list {"a b: c"} $cmd $test
+
+
+sync_after_int
+
+
+set test {a b :c| with WORDBREAKS -= :};  # | = cursor position
+if {[lindex $::BASH_VERSINFO 0] <= 3} {
+    set cmd {COMP_WORDS=(a b :c); COMP_CWORD=2}
+} else {
+    set cmd {COMP_WORDS=(a b : c); COMP_CWORD=3}
+}
+append cmd {; COMP_LINE='a b :c'; COMP_POINT=6}
+assert_bash_exec $cmd $test
+set cmd {_get_comp_words_by_ref -n : words; echo "${words[@]}"}
+assert_bash_list {"a b :c"} $cmd $test
+
+
+sync_after_int
+
+
 teardown

-- 
bash-completion



More information about the Bash-completion-commits mailing list