Search code examples
bashbash-completion

Bash completion broken on short options


I've created my own bash completion function. I've made several edits. The completion itself suits me, but I have broken the auto space after the short options -a, -p, -h

Meaning, when I type editcfg -filTAB it autocompletes to editcfg -file (space after the -file). However, if I type editcfg -pTAB, it won't autospace after the -p.

Function:

_editcfg () 
{ 
    local cur prev opts presets u_opts;
    COMPREPLY=();
    cur="${COMP_WORDS[COMP_CWORD]}";
    prev="${COMP_WORDS[COMP_CWORD-1]}";
    opts=("-n" "-p" "-file" "-a" "-verbose" "-version" "-h");
    presets=("default" "empty");
    u_opts=();
    for i in "${opts[@]}";
    do
        for j in "${COMP_WORDS[@]}";
        do
            if [[ "$i" == "$j" ]]; then
                continue 2;
            fi;
        done;
        u_opts+=("$i");
    done;
    case ${prev} in 
        -p)
            COMPREPLY=($(compgen -W "${presets[*]}" -- ${cur}));
            return 0
        ;;
        -file)
            COMPREPLY=($(compgen -fd -- ${cur} 2>/dev/null));
            return 0
        ;;
        -h | -version)
            u_opts=();
            return 0
        ;;
    esac;
    COMPREPLY=($(compgen -W "${u_opts[*]}" -- ${cur}));
    return 0
}

What did I miss?

Thanks


Solution

  • I updated the 2nd for loop and it worked fine:

    _editcfg () 
    { 
        local cur prev opts presets u_opts;
        COMPREPLY=();
        cur="${COMP_WORDS[COMP_CWORD]}";
        prev="${COMP_WORDS[COMP_CWORD-1]}";
        opts=("-n" "-p" "-file" "-a" "-verbose" "-version" "-h");
        presets=("default" "empty");
        u_opts=();
        for i in "${opts[@]}"; do
            for ((j = 0; j < COMP_CWORD; ++j)) do
                if [[ "$i" == "${COMP_WORDS[j]}" ]]; then
                    continue 2;
                fi;
            done;
            u_opts+=("$i");
        done;
        case ${prev} in 
            -p)
                COMPREPLY=($(compgen -W "${presets[*]}" -- ${cur}));
                return 0
            ;;
            -file)
                COMPREPLY=($(compgen -fd -- ${cur} 2>/dev/null));
                return 0
            ;;
            -h | -version)
                u_opts=();
                return 0
            ;;
        esac;
        COMPREPLY=($(compgen -W "${u_opts[*]}" -- ${cur}));
        return 0
    }