TL;DR
In bash (preferably bash 3+), how can I support empty string ('') as a completion (amongst others) for a value for an option for a command, while also supporting path completions for other values for other options for the same command, with spaces & other special shell characters in the paths getting escaped, slashes being appended to directory paths, etc.?
Detail
I would like to allow an option value for my command to complete to an empty string. That can be achieved via:
_command() {
…
COMPREPLY+=(\'\')
…
}
complete -F _command command
I also want various other option values for the same command to complete to file and/or directory paths, which can contain spaces and/or other characters that must be escaped on the command line. I'd prefer spaces & other such characters to not be escaped in the completion list, but to be escaped if they are in the selected completion that is inserted into the command line.
I also want directories to have a slash (/) appended to them, both in the completion list and if they're selected & inserted into the command line. If a directory is inserted into the command line, I want a space to be appended after the slash iff the directory doesn't contain any paths that would match the selection criteria for the completions. Thus, if a directory contains any paths viable for completion, I can just hit tab again to see / cycle through them.
The above path behavior can be achieved using:
_command() {
…
declare cur="${COMP_WORDS[COMP_CWORD]}"
…
while IFS='' read -r completion; do COMPREPLY+=("${completion}"); done < <(compgen -f -- "${cur}")
…
}
complete -o filenames -F _command command
Instead of:
complete -F _command command
The problem is that the -o filenames option escapes the '' into \'\'.
Instead of using -o filenames for complete, I tried inserting it into my compgen call, but it didn't have any effect:
…
… compgen -o filenames -f -- "${cur}" …
…
I attempted other solutions, like using printf %q …, but none I've tried so far have met all my requirements.
$curso that we can try a few possibilities without having to write a full completion function ourselves.$cur