darckcrystale
darckcrystale

Reputation: 1722

How to autocomplete a bash commandline with file paths?

Context

I am creating a shell program which is a command line tool. I want to create my own auto-completion for this tool.

I want to do two different things (maybe should I post two questions):

my_app_autocomplete file

__my_app_autocomplete()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--help -h --install -i --run -r --rebuild -rb --show-running-containers -ps --stop -s --remove -rm --logs -l --bash -b --sass -css --unit-tests -t"
    containers="nginx php mysql mongo node"
    sass="watch"

    # By default, autocomplete with options
    if [[ ${prev} == my_app ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
    # By default, autocomplete with options
    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
    # For --install and -i options, autocomplete with folder
    if [ ${prev} == --install ] || [ ${prev} == -i ] ; then
        COMPREPLY=( $(compgen -d -- ${cur}) )
        return 0
    fi
    # For --stop --remove --logs and --bash, autocomplete with containers
    if [ ${prev} == --stop ] || [ ${prev} == -s ] || [ ${prev} == --remove ] || [ ${prev} == -rm ] || [ ${prev} == --logs ] || [ ${prev} == -l ] || [ ${prev} == --bash ] || [ ${prev} == -b ] ; then
        COMPREPLY=( $(compgen -W "${containers}" -- ${cur}) )
        return 0
    fi
    # For --sass and -css, complete with sass options
    if [ ${prev} == --sass ] || [ ${prev} == -css ] ; then
        COMPREPLY=( $(compgen -W "${sass}" -- ${cur}) )
        return 0
    fi
    # For --unit-tests and -t, complete with relative to my_app folder paths
    if [ ${prev} == --unit-tests ] || [ ${prev} == -t ] ; then
        COMPREPLY=( $(compgen -d -- ${cur}) )
        return 0
    fi
}
complete -F __my_app_autocomplete my_app

Problem

I struggle on a particular point: auto-complete file paths.

I don't understand compgen options and how to do things with it. Maybe I could try to run a subcommand but I don't know the syntax and I can't find any useful information except man of bash - Programmable completion builtins which does not give much information about compgen.

In this case, when I do:

user@computer:~$ my_app --install D[TAB][TAB]

I would like:

user@computer:~$ my_app --install Documents/

I obtain:

user@computer:~$ myapp --install Documents 

with a blank space at the end of the line, which is a problem because I have to erase it and add a / to be able to redo [TAB][TAB] to auto-complete for sub-directories.

Investigations

-o nospace

With the option -o nospace applied on complete as:

complete -o nospace -F __my_app_autocomplete my_app

the behavior is:

user@computer:~$ myapp --i[TAB][TAB]
user@computer:~$ myapp --install

without space.

user@computer:~$ myapp --install D[TAB][TAB]
user@computer:~$ myapp --install Documents

without space.

Problems:

-o filenames

With the option -o filenames applied on complete as:

complete -o filenames -F __my_app_autocomplete my_app

the behavior is:

user@computer:~$ myapp --i[TAB][TAB]
user@computer:~$ myapp --install

with a space

user@computer:~$ myapp --install D[TAB][TAB]
user@computer:~$ myapp --install Documents/

with a / and without space if it's a directory

user@computer:~$ myapp --install f[TAB][TAB]
user@computer:~$ myapp --install file 

with a space if it's a file

It seems to set paths only for completion not defined in an list of words, so it does not affect other completions, I think it's the first part of what I need.

From a particular directory

I will open another question to avoid mixing things: How to autocomplete a bash commandline with file paths from a specific directory without displaying this directory?

Upvotes: 2

Views: 3057

Answers (1)

D'Arcy Nader
D'Arcy Nader

Reputation: 196

To auto complete file paths

Substitute

complete -F __my_app_autocomplete my_app

with

complete -o filenames -F __my_app_autocomplete my_app

Here you can find all the compgen options explained:

https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html

Upvotes: 1

Related Questions