Modifying $COMP_WORDBREAKS in completion script is not the recommended as it is a global variable and the modification could affect the behavior of other completion scripts. As a workaround, this commit uses the _get_comp_words_by_ref which allows user to exclude characters out of $COMP_WORDBREAKS and reassemble input command line. However, as a side effect, the bash completion module cannot handle ':' and '=' correctly in the resulting completions. Thusly, we need to remove those completions. This will reduce the functionality of some fancy completions. For example, COLUMN?:KEY=VALUE will not complete on KEY and VALUE.
Signed-off-by: Alex Wang <al...@nicira.com> --- tests/completion.at | 14 +++++++------- utilities/ovs-vsctl-bashcomp.bash | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/completion.at b/tests/completion.at index d3b2800..0013efa 100644 --- a/tests/completion.at +++ b/tests/completion.at @@ -345,8 +345,8 @@ AT_SKIP_IF([test -z ${BASH_VERSION+x} || test ${BASH_VERSINFO[[0]]} -lt 4]) OVS_VSWITCHD_START # complete ovs-vsctl --db=* [TAB] -TMP="$(ovs-vsctl --commands | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n') -$(ovs-vsctl --options | grep -- '--' | sed -e 's/=.*$/=/g')" +TMP="$(ovs-vsctl --commands | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n' | sed -e 's/=//g') +$(ovs-vsctl --options | grep -- '--' | sed -e 's/=.*$//g')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "--db=unix:$OVS_RUNDIR/db.sock "], [0], [dnl @@ -405,7 +405,7 @@ AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "destroy Bridge br0 "], ${MATCH} ]) # test +. the first time, an argument is required, after that, it becomes '*'. -TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | awk '/key.*value/ { print $1":"; next } { print $1; next }')" +TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | awk '/key.*value/ { print $1; next } { print $1; next }')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "set Bridge br0 "], [0], [dnl @@ -626,13 +626,13 @@ ${MATCH} # test: _ovs_vsctl_complete_column_optkey_value # # at first, we should complete on column. -TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | awk '/key.*value/ { print $1":"; next } { print $1; next }')" +TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Bridge | awk '/key.*value/ { print $1; next } { print $1; next }')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "set Bridge br0 "], [0], [dnl ${MATCH} ]) -MATCH="$(PREPARE_MATCH_NOSPACE(other_config:))" +MATCH="$(PREPARE_MATCH_NOSPACE(other_config))" AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "set Bridge br0 other"], [0], [dnl ${MATCH} @@ -718,7 +718,7 @@ ${MATCH} # test 'add-port' # after specifying the new port name, we should complete on the column part # of '*COLUMN?:KEY=VALUE'. -TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Port | awk '/key.*value/ { print $1":"; next } { print $1; next }')" +TMP="$(ovsdb-client --no-heading list-columns Open_vSwitch Port | awk '/key.*value/ { print $1; next } { print $1; next }')" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP} --))" AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "add-port br0 new-port "], [0], [dnl @@ -730,7 +730,7 @@ ${MATCH} # test: _ovs_vsctl_complete_dashdash # # after '--', there should be no global options available for completion. -TMP="$(ovs-vsctl --commands | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n')" +TMP="$(ovs-vsctl --commands | cut -d',' -f1-2 | tr -d ',[[]]' | tr -s ' ' '\n' | sed -e s/=//)" MATCH="$(PREPARE_MATCH_NOSPACE(${TMP}))" AT_CHECK_UNQUOTED([ovs-vsctl-bashcomp.bash test "init -- "], [0], [dnl diff --git a/utilities/ovs-vsctl-bashcomp.bash b/utilities/ovs-vsctl-bashcomp.bash index e79c6a2..1a8310b 100755 --- a/utilities/ovs-vsctl-bashcomp.bash +++ b/utilities/ovs-vsctl-bashcomp.bash @@ -36,7 +36,7 @@ _OVS_VSCTL_COMMANDS="$(_ovs_vsctl --commands)" # This doesn't complete on short arguments, so it filters them out. _OVS_VSCTL_OPTIONS="$(_ovs_vsctl --options | awk '/^--/ { print $0 }' \ - | sed -e 's/\(.*\)=ARG/\1=/')" + | sed -e 's/\(.*\)=ARG/\1/')" IFS=$SAVE_IFS declare -A _OVS_VSCTL_PARSED_ARGS @@ -89,6 +89,7 @@ _ovs_vsctl_bashcomp_localopt () { if [[ $result =~ "=" ]]; then options="NOSPACE" fi + result=$(echo "${result}" | sed -e s/=//) printf -- "${options}\nEO\n${result}" } @@ -358,7 +359,7 @@ _ovs_vsctl_complete_column_optkey_value () { $_OVSDB_SERVER_LOCATION Open_vSwitch $table) result=$(printf "%s\n" "${columns}" \ - | awk '/key.*value/ { print $1":"; next } + | awk '/key.*value/ { print $1; next } { print $1; next }' \ | _ovs_vsctl_check_startswith_string "$1" | sort | uniq) fi @@ -627,7 +628,7 @@ _ovs_vsctl_process_messages () { # status of the function _ovs_vsctl_complete_argument represents where # it has determined that the next argument will be. _ovs_vsctl_bashcomp () { - local cur valid_globals cmd_args raw_cmd cmd_pos valid_globals valid_opts + local words cword valid_globals cmd_args raw_cmd cmd_pos valid_globals valid_opts local test="false" # Does not support BASH_VERSION < 4.0 @@ -645,6 +646,12 @@ _ovs_vsctl_bashcomp () { <<< "$tmp" export COMP_WORDS export COMP_CWORD="$((${#COMP_WORDS[@]}-1))" + else + # If not in test mode, reassembles the COMP_WORDS and COMP_CWORD + # using just space as word break. + _get_comp_words_by_ref -n "\"'><=;|&(:" -w words -i cword + COMP_WORDS=( "${words[@]}") + COMP_CWORD=${cword} fi # Extract the conf.db path. @@ -661,13 +668,11 @@ _ovs_vsctl_bashcomp () { _OVS_VSCTL_PARSED_ARGS=() _OVS_VSCTL_NEW_RECORDS=() cmd_pos=-1 - cur=${COMP_WORDS[COMP_CWORD]} valid_globals=true valid_opts=true valid_commands=true given_opts="" index=1 - export COMP_WORDBREAKS=" " for word in "${COMP_WORDS[@]:1:${COMP_CWORD}} "; do _OVS_VSCTL_COMP_NOSPACE=false local completion @@ -760,6 +765,9 @@ _ovs_vsctl_bashcomp () { fi printf "\n" else + # colon, equal sign will mess up the completion output, just + # deletes any completion with those signs. + completion="$(echo "${completion}" | sed -e '/:/d; /=/d')" if [ "${_OVS_VSCTL_COMP_NOSPACE}" = "true" ]; then compopt -o nospace COMPREPLY=( $(compgen -W "${completion}" -- $word) ) -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev