diff --git a/completions/export b/completions/export index 557c52cb..42273a9e 100644 --- a/completions/export +++ b/completions/export @@ -3,23 +3,59 @@ _export() { local cur prev words cword - _init_completion || return + _init_completion -n = || return - case ${words[@]} in - *=\$*) - COMPREPLY=( $( compgen -v -P '$' -- "${cur#*=\$}" ) ) - ;; - *[^=]) - COMPREPLY=( $( compgen -v -S '=' -- "$cur" ) ) - ;; + local i action=variable remove=false + for (( i=1; i < cword; i++ )); do + case ${words[i]} in + -p) + return + ;; + -*f*) + action=function + ;;& + -*n*) + remove=true + ;; + -*) + continue + ;; + esac + break + done + + [[ $cur == *=\$* ]] && { cur=${cur#*=}; _variables; } && return + + case $cur in *=) - COMPREPLY=( "$( eval echo -n \"$`echo ${cur%=}`\" | - ( echo -n \' - sed -e 's/'\''/'\''\\\'\'''\''/g' - echo -n \' ) )" ) + local pval=$( quote "$( eval printf %s \"\$${cur%=}\" )" ) + # Complete previous value if it's not empty. + if [[ $pval != \'\' ]]; then + COMPREPLY=( "$pval" ) + else + cur=${cur#*=} + _filedir + fi + ;; + *=*) + cur=${cur#*=} + _filedir + ;; + *) + if [[ $cword -eq 1 && $cur == -* ]]; then + COMPREPLY=( $( compgen -W \ + '-p $( _parse_usage "$1" )' -- "$cur" ) ) + return + fi + local suffix + if ! $remove; then + suffix+== + compopt -o nospace + fi + COMPREPLY=( $( compgen -A $action -S "$suffix" -- "$cur" ) ) ;; esac } && -complete -F _export -o default -o nospace export +complete -F _export export # ex: ts=4 sw=4 et filetype=sh diff --git a/test/completion/export.exp b/test/completion/export.exp new file mode 100644 index 00000000..bab517a9 --- /dev/null +++ b/test/completion/export.exp @@ -0,0 +1 @@ +assert_source_completions export diff --git a/test/lib/completions/export.exp b/test/lib/completions/export.exp new file mode 100644 index 00000000..84cb9170 --- /dev/null +++ b/test/lib/completions/export.exp @@ -0,0 +1,55 @@ +proc setup {} { + save_env +} + + +proc teardown {} { + assert_env_unmodified { + /OLDPWD=/d + } +} + + +setup + + +assert_complete_any "export BASH" +sync_after_int + + +assert_complete_any "export -n BASH" +sync_after_int + + +assert_no_complete "export -p " +sync_after_int + + +assert_complete_dir {bar "bar bar.d/" foo foo.d/} "export FOO=" \ + fixtures/shared/default +sync_after_int + + +assert_complete_dir {foo foo.d/} "export FOO=f" fixtures/shared/default "" \ + -expect-cmd-minus f +sync_after_int + + +# Functions: _export, _expand, ... +assert_complete_any "export -fn _ex" +sync_after_int + + +assert_complete_any "export -f -n _ex" +sync_after_int + + +assert_complete_any "export FOO=\$BASH" +sync_after_int + + +assert_complete_any "export -" +sync_after_int + + +teardown