Search code examples
linuxbashunixcompletion

custom bash completion with whitespace and paths


I can't figure out what I am doing wrong. I have my bash_completion file setup as such:

_bcd()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $(compgen -W "$(back_directory.pl --complete $cur)" -- $cur) )
}
complete -o filenames -o nospace -F _bcd bcd

back_directory.pl is a program that will return directories paths up the tree: back_directory.pl --complete Th produces: This\ test/ But:

22:50:24-Josh@Joshuas-MacBook-Air:~/Desktop/bcd/This test/more    white/t$ bcd Th<TAB><TAB>
This   test/

As shown above, it doesn't auto complete for directories with whitespace in them (but it shows the completion option).

It should look like this: bcd This\ test/

I thought -o filenames should add the backslashes to escape the whitespace. Thanks for any help :)


Solution

  • Your single call to compgen produces a single word (containing embdedded newlines), so you are only adding a single possible completion to COMPREPLY. Instead, you need to process the output of back_directory.pl one item at a time. Each item is tested as a possible match, and if compgen returns a non-empty string, add that to COMPREPLY.

    _bcd() {
        local cur=${COMP_WORDS[COMP_CWORD]}
        IFS=: read -a matches < <(back_directory.pl --complete "$cur")
        for match in "${matches[@]}"; do
            possible=$(IFS= compgen -W "$match" -- "$cur")
            [[ $possible ] && COMPREPLY+=( "$possible" )
        done
    }
    

    (Note: I'm assuming back_directory.pl will produce a single line of output similar to

    directory1:directory two:directory three:directory4
    

    )