Default Bash Autocompletion

I was writing a bash auto completion script, following this tutorial.

But one thing that stuck me for a while was that I could not use default bash auto completion for some options.

Let’s say I have a command called mycmd, which has such a synopsis:

Usage: mycmd [options]

Options:
  hello       Say "Hello"
  help        Show this help
  show file   Show file

It’s not hard to write a script like this following the tutorial.

#!/bin/bash

_mycmd()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="hello help show"

    case "${prev}" in
        *)
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
            ;;
    esac
}
complete -F _mycmd mycmd

It works pretty well that It can auto complete the options “hello”, “help” or “show”. But I also want it to show possible files after mycmd show just like cat.

I have tried like compgen -f or ls -1p but they can not handle spaces in the file name or home directory (~/).

After some exploration (i.e. complete | grep cat), I found out that _longopt looks like what I want.

#!/bin/bash

_mycmd()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="hello help show"

    case "${prev}" in
        show)
            _longopt
            return 0
            ;;
        *)
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
            ;;
    esac
}
complete -F _mycmd mycmd

It works perfect!

Leave a Reply

Your email address will not be published.

86 − = 81