0

I'm trying to filter bash-completion suggestions. Here awf-gtk2 -s abc.png [TAB] display -h --help -s --screenshot (it's ridiculous) / and awf-gtk2 -s[TAB] add a space after -s (perfect), with:

_awf_gtk2_complete() {
    local cur prev
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    local opts="-h --help -s --screenshot"
    case "$prev" in
        -h|--help|-v|--version|-l|--list-themes)
            return 1 # stop
            ;;
        -s|--screenshot)
            COMPREPLY=( $(compgen -d -- "$cur") )
            return 0
            ;;
    esac
    COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
}
complete -F _awf_gtk2_complete awf-gtk2

With ChatGPT (sorry), we did that:

# made in chatGPT
_awf_gtk3_complete() {
    local cur prev
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    local all_opts=(-h --help -v --version -l --list-themes -t --theme -s --screenshot --ltr --rtl)
    local single_opts=(-h --help -v --version -l --list-themes)

    declare -A opt_aliases=(
        [-h]=--help
        [--help]=-h
        [-v]=--version
        [--version]=-v
        [-l]=--list-themes
        [--list-themes]=-l
        [-t]=--theme
        [--theme]=-t
        [-s]=--screenshot
        [--screenshot]=-s
    )

    case "$prev" in
        -h|--help|-v|--version|-l|--list-themes)
            return 1 # stop
            ;;
        -s|--screenshot)
            COMPREPLY=( $(compgen -d -- "$cur") )
            return 0
            ;;
    esac

    local used=()
    local word
    for word in "${COMP_WORDS[@]:1}"; do
        if [[ "$word" == -* ]]; then
            used+=("$word")
            [[ -n "${opt_aliases[$word]}" ]] && used+=("${opt_aliases[$word]}")
        fi
    done

    local hide_single_use=false
    for word in "${used[@]}"; do
        case "$word" in
            -t|--theme|-s|--screenshot|--ltr|--rtl)
                hide_single_use=true
                break
                ;;
        esac
    done

    local remaining_opts=()
    local opt
    for opt in "${all_opts[@]}"; do
        local skip=false
        for u in "${used[@]}"; do
            [[ "$opt" == "$u" ]] && skip=true && break
        done
        if $hide_single_use; then
            for su in "${single_opts[@]}"; do
                [[ "$opt" == "$su" ]] && skip=true && break
            done
        fi
        $skip || remaining_opts+=("$opt")
    done

    local opts=${remaining_opts[*]}
    COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
}
complete -F _awf_gtk3_complete awf-gtk3

The idea:

  • if you are using -h --help -v --version -l --list-themes, completion suggests nothing else (it's ok)
  • if you are using -t --theme, completion suggests themes names by running the program (it's ok)
  • if you are using a short option, completion doesn't suggests the corresponding long option (it's ok)
  • if you are using one option, completion doesn't suggests again the same option (it's ok)
  • if you are using --ltr, completion doesn't suggests --rtl (but not yet, and it's not the problem)

The problem is: awf-gtk3 -t[TAB] or awf-gtk3 --theme[TAB] does NOT add a space! (awf-gtk3 --th[TAB] add a space and it's perfect). Why?

1 Answer 1

0

So, the problem is:

    local used=()
    local word
    for word in "${COMP_WORDS[@]:1}"; do
        ...
    done

The solution is:

    local used=()
    for ((i = 1; i < COMP_CWORD; i++)); do
        local word="${COMP_WORDS[$i]}"
        ...
    done

I'm not sure to understand why.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.