0

I'm trying to create a command completion function, and I was following this guide. This is approximately how it looks:

function __my_completion ()
{
    local cur prev opts opts_log opts_import
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="-h --help -d --directory -v --version -l --log-level -q --quiet"
    opts_log="trace debug info warn err critical off"

    if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
        COMPREPLY=( $(compgen -o nospace -d -W "${opts}" -- ${cur}) )
        return 0
    fi
    case "${prev}" in
        -d|--directory)
            COMPREPLY=( $(compgen -o nospace -d ${cur}) )
        ;;
        -l|--log-level)
            COMPREPLY=( $(compgen -W "${opts_log}" -- ${cur}) )
        ;;
    esac
}

complete -F __my_completion myProg

My problem is: whenever any word is completed, a space is added to the end. That's fine for normal options, but it's also done with directories, despite the -o nospace -d option combination. That is very annoying, as it slows down navigation and is very unintuitive.

Why is that and how can I correct it?

Also, while I'm here, what's the single ? for in one of the examples in the linked guide? It's in the line

COMPREPLY=( $(compgen -f ? ${cur}) )
RL-S
  • 131
  • 1
  • 4

1 Answers1

1

At least a partial solution: While compgen ignores the -o nospace option, complete respects it. This sadly means that either all options have spaces added after them, or none. Here's the code:

#/usr/bin/env bash

function __my_completion ()
{
    local cur prev opts opts_log
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="-h --help -d --directory -v --version -l --log-level -q --quiet"
    opts_log="trace debug info warn err critical off"
    local opts_dir=( $(compgen -d -S "/" -- ${cur}) )

    if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ${opts_dir[@]} )
        return 0
    fi
    case "${prev}" in
        -d|--directory)
            COMPREPLY=( ${opts_dir[@]} )
        ;;
        -l|--log-level)
            COMPREPLY=( $(compgen -W "${opts_log}" -- ${cur}) )
        ;;
    esac
}

complete -o nospace -F __my_completion myProg

Adding -S " " to the other options does not add the space back in, either.

RL-S
  • 131
  • 1
  • 4