[Bash-completion-devel] RFC: Turn on -o filenames in _filedir() if compopt is available

Freddy Vulto fvulto at gmail.com
Sat Dec 5 09:30:10 UTC 2009

On 091205 00:43, gibboris at gmail.com wrote:
> What are the "manual tweak" bash 3 compatibles you think about ?
> The only thing I imagine (saw in upstream mpc completion) is to append ' '
> or '/' (and do backslashes hell tricks) to emulate -o filename while using a
> global -o nospace (don't know if the 'idea' has been dug before)
> From what I see, the wrapper only way to 'know' the bash 3 completion currently
> used is to sed $(complete -p $cmd) though the {run,load}time behavior is still
> unknown to me.

Yes, the bash-3 improvements I'm thinking about are emulating `-o
filenames' and (also necessary for bash-4) `+o nospace'.

Indeed from within a completion, `_filedir' should be able to figure out if `-o
filenames' is in effect, here's the prove:

    _a() {
        if [[ "$(complete -p ${COMP_WORDS[0]})" != *"-o filenames"* ]]; then
            echo Emulate -o filenames
    complete -F _a a

These would be the pseudo-codes:

    _filedir() {
        if $bash_version >= 4
            compopt -o filenames
        elseif `-o filename' isn't in effect for $CWORDS[0]
            loop through completions
                emulate `-o filanames': escape spaces, append slashes, etc.


    __space_suffix_completions() {
        if $bash_version < 4.1 (?)
            loop through completions
                append a space
            # In case `-o nospace' is in effect, disable it.
            # Unfortunately `compopt +o' is not working in bash-4.0, maybe 4.1?
            # See: http://www.mail-archive.com/bug-bash@gnu.org/msg06183.html
            compopt +o nospace

In fact I've already been trying on a real `__space_suffix_completions()' to
use for the `finger' completion, but it's not finished yet.  Nevertheless, here
it is sofar:

    # Usage: __space_suffix_completions CWORD
    __space_suffix_completions() {
        # Loop through completions
        local i=${#COMPREPLY[*]}
        while [ $((--i)) -ge 0 ]; do
            # Is completion empty while there are other completions?
            if [[ "${COMPREPLY[$i]}" == "" && ${#COMPREPLY[*]} -gt 1 ]]; then
                # Remove item
                unset COMPREPLY[$i]
            elif [[ "${COMPREPLY[$i]}" == "" && ${#COMPREPLY[*]} -eq 1 ]]; then
                local WORDBREAKS=$COMP_WORDBREAKS
                [ ${BASH_VERSINFO[0]} -lt 4 ] && WORDBREAKS=" \t\n\"'><=;|&(:)@"
                # Remove leftmost characters of CWORD until the last COMP_WORDBREAKS char
                local totrim=${COMP_WORDS[$COMP_CWORD]} trimmed=$totrim
                while true; do
                    [ "$trimmed" = "$totrim" ] && break
                COMPREPLY=($trimmed" ")
                # Suffix space
                #COMPREPLY[$i]=$(__ltrim_wordbreak "${COMPREPLY[$i]} ")
                COMPREPLY[$i]="${COMPREPLY[$i]} "
    }; # __space_suffix_completions()


Freddy Vulto

More information about the Bash-completion-devel mailing list