10

Is it possible to get command-line autocompletion of python -m package.subpackage.module?

This is similar to, but not the same as, python ./package/subpackage/module.py, which does autocomplete the directory and file paths. However with -m, python runs the library's module as a script with the appropriate namespacing and import paths.

I'd like to be able to do python -m package.s[TAB] and get autocompletion to subpackage.

Is this feature built in somewhere, or how can I set it up?

Amessihel
  • 5,891
  • 3
  • 16
  • 40
Hatshepsut
  • 5,962
  • 8
  • 44
  • 80

1 Answers1

2

As said in the comment section, you need to extend the bash-completion tool. Then, you'll create a script which handles the cases you need (ie: when the last argument was -m).

This little sample below shows a start for your custom completion script. Let's name it python_completion.sh.

_python_target() {
    local cur prev opts

    # Retrieving the current typed argument
    cur="${COMP_WORDS[COMP_CWORD]}"

    # Retrieving the previous typed argument ("-m" for example)
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Preparing an array to store available list for completions
    # COMREPLY will be checked to suggest the list
    COMPREPLY=()

    # Here, we'll only handle the case of "-m"
    # Hence, the classic autocompletion is disabled
    # (ie COMREPLY stays an empty array)
    if [[ "$prev" != "-m" ]]
    then
        return 0
    fi

    # Retrieving paths and converts their separators into dots
    # (if packages doesn't exist, same thing, empty array)
    if [[ ! -e "./package" ]]
    then
       return 0
    fi

    # Otherwise, we retrieve first the paths starting with "./package"
    # and converts their separators into dots
    opts="$(find ./package -type d | sed -e 's+/+.+g' -e 's/^\.//' | head)"

    # We store the whole list by invoking "compgen" and filling
    # COMREPLY with its output content.
    COMPREPLY=($(compgen -W "$opts" -- "$cur"))

}

complete -F _python_target python

(Warning. This script has a flaw, it won't work with filenames containing spaces). To test it, run it in the current environnement:

. ./python_completion.sh

And test it:

python -m packag[TAB]

Here is a tutorial to continue in this way.

Amessihel
  • 5,891
  • 3
  • 16
  • 40