[Bash-completion-commits] [SCM] bash-completion branch, master, updated. ebdd9cefdc33a80aa51192df66e24616ddb4a9b2

Crestez Dan Leonard cdleonard at gmail.com
Tue Feb 9 13:57:43 UTC 2010


The following commit has been merged in the master branch:
commit ebdd9cefdc33a80aa51192df66e24616ddb4a9b2
Merge: 6b30acc9ac24a2bf9650499da7d805ad5cf4fea8 aac11de466f9a22312329e91769d0c84ae347407
Author: Crestez Dan Leonard <cdleonard at gmail.com>
Date:   Tue Feb 9 15:45:40 2010 +0200

    Merge branch 'space-fix': Fix tests when BASH_COMPLETION or TESTDIR contain
    spaces.
    
    Conflicts:
    	CHANGES

diff --combined CHANGES
index 2b0ff4e,c6baded..db5ef76
--- a/CHANGES
+++ b/CHANGES
@@@ -68,7 -68,7 +68,8 @@@ bash-completion (2.x
    * Improve ssh -o suboption completion (Alioth: #312122).
    * Fix NFS mounts completion (Alioth: #312285).
    * Fix completion of usernames (Alioth: #311396, Debian: #511788).
 +  * Fix chown test crashing on systems with no root group (Alioth: #312306).
+   * Fixed tests when BASH_COMPLETION or TESTDIR contain spaces.
  
    [ Raphaël Droz ]
    * Add xsltproc completion (Alioth: #311843).
diff --combined bash_completion
index 84f9bd0,8467272..904a8be
--- a/bash_completion
+++ b/bash_completion
@@@ -90,7 -90,7 +90,7 @@@ complete -f -X '!*.@(@(?(e)ps|?(E)PS|pd
  complete -f -X '!*.@(okular|@(?(e|x)ps|?(E|X)PS|pdf|PDF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb|FB|mobi|MOBI|g3|G3|chm|CHM|fdf|FDF)?(.?(gz|GZ|bz2|BZ2)))' okular
  complete -f -X '!*.@(?(e)ps|?(E)PS|pdf|PDF)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr
  complete -f -X '!*.texi*' makeinfo texi2html
 -complete -f -X '!*.@(?(la)tex|?(LA)TEX|texi|TEXI|dtx|DTX|ins|INS)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi
 +complete -f -X '!*.@(?(la)tex|?(LA)TEX|texi|TEXI|dtx|DTX|ins|INS|ltx|LTX)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi
  complete -f -X '!*.@(mp3|MP3)' mpg123 mpg321 madplay
  complete -f -X '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|wav|WAV|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))' xine aaxine fbxine kaffeine dragon
  complete -f -X '!*.@(avi|asf|wmv)' aviplay
@@@ -253,142 -253,6 +253,142 @@@ __reassemble_comp_words_by_ref() 
  } # __reassemble_comp_words_by_ref()
  
  
 +# @param $1 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 $1 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.
 +# @param $2 words  Name of variable to return words to
 +# @param $3 cword  Name of variable to return cword to
 +# @param $4 cur  Name of variable to return current word to complete to
 +# @see ___get_cword_at_cursor_by_ref()
 +__get_cword_at_cursor_by_ref() {
 +    # NOTE: The call to the main function ___get_cword_at_cursor_by_ref() is
 +    #       wrapped to make collisions with local variable names less likely.
 +    local __words __cword __cur
 +    ___get_cword_at_cursor_by_ref "$1" __words __cword __cur
 +
 +    eval $2=\( \"\${__words[@]}\" \)
 +    eval $3=\$__cword
 +    eval $4=\$__cur
 +}
 +
 +
 +# @param $1 exclude
 +# @param $2 words  Name of variable to return words to
 +# @param $3 cword  Name of variable to return cword to
 +# @param $4 cur  Name of variable to return current word to complete to
 +# @note  Do not call this function directly but call 
 +#     `__get_cword_at_cursor_by_ref()' instead to make variable name collisions
 +#     less likely
 +# @see __get_cword_at_cursor_by_ref()
 +___get_cword_at_cursor_by_ref() {
 +    local cword words
 +    __reassemble_comp_words_by_ref "$1" words cword
 +
 +    local i
 +    local cur="$COMP_LINE"
 +    local index="$COMP_POINT"
 +    for (( i = 0; i <= cword; ++i )); do
 +        while [[
 +            # Current word fits in $cur?
 +            "${#cur}" -ge ${#words[i]} &&
 +            # $cur doesn't match cword?
 +            "${cur:0:${#words[i]}}" != "${words[i]}"
 +        ]]; do
 +            # Strip first character
 +            cur="${cur:1}"
 +            # Decrease cursor position
 +            ((index--))
 +        done
 +
 +        # Does found word matches cword?
 +        if [[ "$i" -lt "$cword" ]]; then
 +            # No, cword lies further;
 +            local old_size="${#cur}"
 +            cur="${cur#${words[i]}}"
 +            local new_size="${#cur}"
 +            index=$(( index - old_size + new_size ))
 +        fi
 +    done
 +
 +    if [[ "${words[cword]:0:${#cur}}" != "$cur" ]]; then
 +        # We messed up. At least return the whole word so things keep working
 +        eval $4=\"\${words[cword]}\"
 +    else
 +        eval $4=\"\${cur:0:\$index}\"
 +    fi
 +
 +    eval $2=\( \"\${words[@]}\" \)
 +    eval $3=\$cword
 +}
 +
 +
 +# Get the word to complete and optional previous words.
 +# This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
 +# where the user is completing in the middle of a word.
 +# (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]]
 +# 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
 +}
 +
 +
 +# @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 $@  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
 +        case $flag in
 +            n) exclude=$OPTARG ;;
 +        esac
 +    done
 +    varnames=( ${!OPTIND} )
 +    let "OPTIND += 1"
 +    while [[ $# -ge $OPTIND ]]; do 
 +        varnames+=( ${!OPTIND} )
 +        let "OPTIND += 1"
 +    done
 +
 +    __get_cword_at_cursor_by_ref "$exclude" words cword cur
 +
 +    eval $1=\( \"\${words[@]}\" \)
 +    eval $2=\$cword
 +    eval $3=\$cur
 +    eval $4=\( \"\${varnames[@]}\" \)
 +}
 +
 +
  # Get the word to complete.
  # This is nicer than ${COMP_WORDS[$COMP_CWORD]}, since it handles cases
  # where the user is completing in the middle of a word.
@@@ -1810,7 -1674,7 +1810,7 @@@ _filedir_xspec(
  
      # get first exclusion compspec that matches this command
      xspec=$( awk "/^complete[ \t]+.*[ \t]${1##*/}([ \t]|\$)/ { print \$0; exit }" \
-         $BASH_COMPLETION )
+         "$BASH_COMPLETION" )
      # prune to leave nothing but the -X spec
      xspec=${xspec#*-X }
      xspec=${xspec%% *}
@@@ -1837,7 -1701,7 +1837,7 @@@
  
      COMPREPLY=( "${toks[@]}" )
  }
- list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' $BASH_COMPLETION | \
+ list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' "$BASH_COMPLETION" | \
      # read exclusion compspecs
      (
      while read line
@@@ -1863,19 -1727,19 +1863,19 @@@ unset lis
  # source completion directory definitions
  if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
      -x $BASH_COMPLETION_COMPAT_DIR ]]; then
-     for i in $(LC_ALL=C command ls $BASH_COMPLETION_COMPAT_DIR); do
+     for i in $(LC_ALL=C command ls "$BASH_COMPLETION_COMPAT_DIR"); do
          i=$BASH_COMPLETION_COMPAT_DIR/$i
          [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)) \
-             && ( -f $i || -h $i ) && -r $i ]] && . $i
+             && ( -f $i || -h $i ) && -r $i ]] && . "$i"
      done
  fi
  if [[ $BASH_COMPLETION_DIR != $BASH_COMPLETION_COMPAT_DIR && \
      -d $BASH_COMPLETION_DIR && -r $BASH_COMPLETION_DIR && \
      -x $BASH_COMPLETION_DIR ]]; then
-     for i in $(LC_ALL=C command ls $BASH_COMPLETION_DIR); do
+     for i in $(LC_ALL=C command ls "$BASH_COMPLETION_DIR"); do
          i=$BASH_COMPLETION_DIR/$i
          [[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)) \
-             && ( -f $i || -h $i ) && -r $i ]] && . $i
+             && ( -f $i || -h $i ) && -r $i ]] && . "$i"
      done
  fi
  unset i
diff --combined test/lib/completions/screen.exp
index 53e94b1,f486b46..62c5736
--- a/test/lib/completions/screen.exp
+++ b/test/lib/completions/screen.exp
@@@ -18,7 -18,7 +18,7 @@@ sync_after_in
  
  
  set test "-c should complete files/dirs"
 -set dir fixture1
 +set dir fixtures/shared/default
  set prompt "/$dir/@"
  assert_bash_exec "cd $dir" "" $prompt
  set cmd "screen -c "
@@@ -42,7 -42,7 +42,7 @@@ expect 
      default { unresolved "$test" }
  }; # expect
  sync_after_int $prompt
- assert_bash_exec "cd \$TESTDIR"
+ assert_bash_exec {cd "$TESTDIR"}
  
  
  
diff --combined test/lib/completions/ssh.exp
index 2bec70c,8a0d88d..91955c1
--- a/test/lib/completions/ssh.exp
+++ b/test/lib/completions/ssh.exp
@@@ -29,7 -29,7 +29,7 @@@ expect 
      default { unresolved "$test" }
  }; # expect
  sync_after_int $prompt
- assert_bash_exec "cd \$TESTDIR"
+ assert_bash_exec {cd "$TESTDIR"}
  
  
  sync_after_int
@@@ -52,17 -52,30 +52,17 @@@ sync_after_in
  
  
  set test "First argument shouldn't complete with commands"
 -# NOTE: This test assumes the machine running this test has a command "bash"
 -#       but no host named "bash" ...
 +# NOTE: This test assumes there's a command "bash" and no host named "bash"
  set cmd "ssh bas"
 -send "$cmd\t"
 -expect -ex "$cmd"
 -expect {
 -    -timeout 1
 -        # In case multiple commands `bas*' - besides `bash' - are completed
 -    -re "^\r\n.*bash.*\r\n/@$cmd$" { fail "$test" }
 -        # In case the single command `bash' is completed
 -    -re "h $" { fail "$test" }
 -        # In case the hostname `bash_completion' is completed.
 -        # See `scp' tests in `lib/completions/scp.exp'
 -    -re "h_completion $" { pass "$test" }
 -    -re ".+" { unresolved "$test" }
 -    timeout { pass "$test" }
 -}; # expect
 +assert_complete [get_known_hosts "bas"] $cmd $test
  
  
  sync_after_int
  
  
  set test "First argument should complete partial hostname"
 -assert_complete_partial [get_hosts] ssh "" $test /@ 20 [list "ltrim_colon_completions"]
 +assert_complete_partial [get_hosts] ssh "" $test /@ 20 \
 +    [list "ltrim_colon_completions"]
  
  
  sync_after_int
@@@ -84,7 -97,7 +84,7 @@@ expect 
      default { unresolved "$test" }
  }; # expect
  sync_after_int $prompt
- assert_bash_exec "cd \$TESTDIR"
+ assert_bash_exec {cd "$TESTDIR"}
  
  
  sync_after_int
diff --combined test/lib/library.exp
index 0092f3f,fa554c7..00dd846
--- a/test/lib/library.exp
+++ b/test/lib/library.exp
@@@ -79,22 -79,18 +79,22 @@@ proc assert_bash_type {command} 
  # @result boolean  True if successful, False if not
  proc assert_bash_list {expected cmd {test ""} {prompt /@} {size 20}} {
      if {$test == ""} {set test "$cmd should show expected output"}
 -    send "$cmd\r"
 -    expect -ex "$cmd\r\n"
 -
 -    if {[match_items $expected $test $prompt $size]} {
 -        expect {
 -            -re $prompt { pass "$test" }
 -            -re eof { unresolved "eof" }
 -        }; # expect
 +    if {[llength $expected] == 0} {
 +        assert_no_output $cmd $test $prompt
      } else {
 -        fail "$test"
 -    }; # if
 -}; # assert_bash_list()
 +        send "$cmd\r"
 +        expect -ex "$cmd\r\n"
 +
 +        if {[match_items $expected $test $prompt $size]} {
 +            expect {
 +                -re $prompt { pass "$test" }
 +                -re eof { unresolved "eof" }
 +            }
 +        } else {
 +            fail "$test"
 +        }
 +    }
 +}
  
  
  proc assert_bash_list_dir {expected cmd dir {test ""} {prompt /@} {size 20}} {
@@@ -102,7 -98,7 +102,7 @@@
      assert_bash_exec "cd $dir" "" $prompt
      assert_bash_list $expected $cmd $test $prompt $size
      sync_after_int $prompt
-     assert_bash_exec "cd \$TESTDIR"
+     assert_bash_exec {cd "$TESTDIR"}
  }; # assert_bash_list_dir()
  
  
@@@ -272,7 -268,7 +272,7 @@@ proc assert_complete_dir {expected cmd 
      assert_bash_exec "cd $dir" "" $prompt
      assert_complete $expected $cmd $test $prompt $size $cword
      sync_after_int $prompt
-     assert_bash_exec "cd \$TESTDIR"
+     assert_bash_exec {cd "$TESTDIR"}
  }; # assert_complete_dir
      
  
@@@ -455,43 -451,6 +455,43 @@@ proc assert_no_complete {{cmd} {test ""
  }; # assert_no_complete()
  
  
 +# Check that no output is generated on a certain command.
 +# @param string $cmd  The command to attempt to complete.
 +# @param string $test  Optional parameter with test name.
 +# @param string $prompt  (optional) Bash prompt.  Default is "/@"
 +proc assert_no_output {{cmd} {test ""} {prompt /@}} {
 +    if {[string length $test] == 0} {
 +        set test "$cmd shouldn't generate output"
 +    }
 +
 +    send "$cmd\r"
 +    expect -ex "$cmd"
 +
 +    expect {
 +        -re "^\r\n$prompt$" { pass "$test" }
 +        default { fail "$test" }
 +        timeout { fail "$test" }
 +    }
 +}
 +
 +
 +# Source/run file with additional tests if completion for the specified command
 +# is installed in bash.
 +# @param string $command  Command to check completion availability for.
 +# @param string $file  (optional) File to source/run.  Default is
 +#                      "lib/completions/$cmd.exp".
 +proc assert_source_completions {command {file ""}} {
 +    if {[is_bash_completion_installed_for $command]} {
 +        if {[string length $file] == 0} {
 +            set file "lib/completions/$command.exp"
 +        }
 +        source $file
 +    } else {
 +        untested $command
 +    }
 +}; # assert_source_completions()
 +
 +
  # Sort list.
  # `exec sort' is used instead of `lsort' to achieve exactly the
  #  same sort order as in bash.
@@@ -503,12 -462,10 +503,12 @@@ proc bash_sort {items} 
  
  
  # Get 'known' hostnames.  Looks also in ssh's 'known_hosts' files.
 +# @param string cword  (optional) Word, hosts should start with.
  # @return list  Hostnames
  # @see get_hosts()
 -proc get_known_hosts {} {
 -    assert_bash_exec {_known_hosts_real ''; echo_array COMPREPLY} {} /@ result
 +proc get_known_hosts {{cword ''}} {
 +    assert_bash_exec "_known_hosts_real '$cword'; echo_array COMPREPLY" \
 +        {} /@ result
      return $result
  }; # get_known_hosts()
  
@@@ -575,24 -532,6 +575,24 @@@ proc init_tcl_bash_globals {} 
  }; # init_tcl_bash_globals()
  
  
 +# Check whether completion is installed for the specified command by executing
 +# `complete -p ...' in bash.
 +# @param string $command  Command to check completion availability for.
 +# @return boolean  True (1) if completion is installed, False (0) if not.
 +proc is_bash_completion_installed_for {command} {
 +    set test "$command should have completion installed in bash"
 +    set cmd "complete -p $command &> /dev/null && echo -n 0 || echo -n 1"  
 +    send "$cmd\r"
 +    expect "$cmd\r\n"
 +    expect {
 +        -ex 0 { set result true }
 +        -ex 1 { set result false }
 +    }
 +    expect "/@"
 +    return $result
 +}; # is_bash_completion_installed_for()
 +
 +
  # Detect if test suite is running under Cygwin/Windows
  proc is_cygwin {} {
      expr {[string first [string tolower [exec uname -s]] cygwin] >= 0}
@@@ -692,16 -631,16 +692,16 @@@ proc save_env {{file ""}} 
  # @param string  File to save the environment to.  Default is "$TESTDIR/tmp/env1~".
  # @see assert_env_unmodified()
  proc _save_env {{file ""}} {
-     assert_bash_exec "{ set; declare -F; shopt -p; } > $file"
+     assert_bash_exec "{ set; declare -F; shopt -p; } > \"$file\""
  }; # _save_env()
  
  
  # Source bash_completion package
  proc source_bash_completion {} {
-     assert_bash_exec {BASH_COMPLETION_DIR=$(cd $TESTDIR/..; pwd)/contrib}
+     assert_bash_exec {BASH_COMPLETION_DIR=$(cd "$TESTDIR/.."; pwd)/contrib}
      assert_bash_exec {BASH_COMPLETION_COMPAT_DIR=$BASH_COMPLETION_DIR}
-     assert_bash_exec {BASH_COMPLETION=$(cd $TESTDIR/..; pwd)/bash_completion}
-     assert_bash_exec {source $BASH_COMPLETION}
+     assert_bash_exec {BASH_COMPLETION=$(cd "$TESTDIR/.."; pwd)/bash_completion}
+     assert_bash_exec {source "$BASH_COMPLETION"}
  }; # source_bash_completion()
  
  
@@@ -745,73 -684,6 +745,73 @@@ proc split_words_bash {line} 
  }; # split_words_bash()
  
  
 +# Given a list of items this proc finds a (part, full) pair so that when
 +# completing from $part $full will be the only option.
 +#
 +# Arguments:
 +#       list        The list of full completions.
 +#       partName    Output parameter for the partial string.
 +#       fullName    Output parameter for the full string, member of item.
 +#
 +# Results:
 +#       1, or 0 if no suitable result was found.
 +proc find_unique_completion_pair {{list} {partName} {fullName}} {
 +    upvar $partName part
 +    upvar $fullName full
 +    set bestscore 0
 +    set list [lsort $list]
 +    set n [llength $list]
 +    for {set i 0} {$i < $n} {incr i} {
 +        set cur [lindex $list $i]
 +        set curlen [string length $cur]
 +
 +        set prev [lindex $list [expr {$i - 1}]]
 +        set next [lindex $list [expr {$i + 1}]]
 +        set diffprev [expr {$prev == ""}]
 +        set diffnext [expr {$next == ""}]
 +
 +        # Analyse each item of the list and look for the minimum length of the
 +        # partial prefix which is distinct from both $next and $prev. The list
 +        # is sorted so the prefix will be unique in the entire list.
 +        #
 +        # In the worst case we analyse every character in the list 3 times.
 +        # That's actually very fast, sorting could take more.
 +        for {set j 0} {$j < $curlen} {incr j} {
 +            set curchar [string index $cur $j]
 +            if {!$diffprev && [string index $prev $j] != $curchar} {
 +                set diffprev 1
 +            }
 +            if {!$diffnext && [string index $next $j] != $curchar} {
 +                set diffnext 1
 +            }
 +            if {$diffnext && $diffprev} {
 +                break
 +            }
 +        }
 +
 +        # At the end of the loop $j is the index of last character of
 +        # the unique partial prefix. The length is one plus that.
 +        set parlen [expr {$j + 1}]
 +        if {$parlen >= $curlen} {
 +            continue
 +        }
 +
 +        # Try to find the most "readable pair"; look for a long pair where
 +        # $part is about half of $full.
 +        if {$parlen < $curlen / 2} {
 +            set parlen [expr {$curlen / 2}]
 +        }
 +        set score [expr {$curlen - $parlen}]
 +        if {$score > $bestscore} {
 +            set bestscore $score
 +            set part [string range $cur 0 [expr {$parlen - 1}]]
 +            set full $cur
 +        }
 +    }
 +    return [expr {$bestscore != 0}]
 +}
 +
 +
  # Start bash running as test environment.
  proc start_bash {} {
      global TESTDIR TOOL_EXECUTABLE spawn_id

-- 
bash-completion



More information about the Bash-completion-commits mailing list