Skip to content

How to Enable CLI Command Argument Completion

Enable Argument Completion from Scratch

For example, you have a command mycommand with subcommand (arguments) start, stop, status, restart. You want to enable argument completion for it.

Step 1: Create a script to generate completions for your command.

e.g. Given argument s, return start status stop.

# autocomplete.py
import sys

def get_completions(command_prefix):
    commands = ['start', 'stop', 'status', 'restart']
    return [c for c in commands if c.startswith(command_prefix)]

if __name__ == "__main__":
    prefix = sys.argv[1]  # Passed by Bash completion script
    completions = get_completions(prefix)
    print(' '.join(completions))

Step 2: Bash script for handling completions:

# Completion setup
# Run it in the current shell or add it to your .bashrc or .bash_profile
_my_command_complete() {
    local current_word="${COMP_WORDS[COMP_CWORD]}"
    local completions="$(python autocomplete.py "${current_word}")"
    COMPREPLY=($(compgen -W "${completions}" -- ${current_word}))
}
complete -F _my_command_complete mycommand

Step 3: Try with tab:

touch mycommand
chmod +x mycommand
./mycommand s <TAB>
start   status  stop

Enable Argument Completion in Python with argcomplete

Ref: https://kislyuk.github.io/argcomplete/

argcomplete is a Python package that enables argument completion for argparse-based scripts. It provides a way to complete arguments for your script in the shell.

First, you need to install the argcomplete Python package. You can do this using pip:

pip install argcomplete

Next, you need to integrate argcomplete with your argparse-based script. Here are the steps you can follow to enable auto-completion for your script.

Step 1: Modify Your Python Script

Add the PYTHON_ARGCOMPLETE_OK marker and a call to argcomplete.autocomplete() to your Python application as follows:

# awshelper.py
# PYTHON_ARGCOMPLETE_OK
import argparse
import argcomplete

def cli_list_ec2_instances(args):
    print("Listing EC2 instances")

def cli_create_ec2_instance(args):
    print(f"Creating EC2 instance with name: {args.name}")

def main():
    parser = argparse.ArgumentParser(description="aws helper")
    subparsers = parser.add_subparsers(title="commands")

    ec2_ls_parser = subparsers.add_parser("ec2.ls", help="List EC2 instances")
    ec2_ls_parser.set_defaults(func=cli_list_ec2_instances)

    ec2_create_parser = subparsers.add_parser("ec2.create", help="Create EC2 instance")
    ec2_create_parser.add_argument("name", help="Instance name")

    # Activate the argcomplete inside the script
    argcomplete.autocomplete(parser)

    args = parser.parse_args()
    if hasattr(args, 'func'):
        args.func(args)

if __name__ == "__main__":
    main()

Step 2: Register your Python application with your shell’s completion framework

Run in the current shell or add it to your shell's configuration file (.bashrc, .bash_profile, .zshrc, etc.):

eval "$(register-python-argcomplete awshelper.py)"

Or you can enable argcomplete globally without registering each application individually - recommended:

activate-global-python-argcomplete

It creates a generic completion script which sources argcomplete/bash_completion.d/_python-argcomplete and it looks for marker PYTHON_ARGCOMPLETE_OK in your Python script to enable completion.

 cat ~/.bash_completion

# Begin added by argcomplete
source "/home/peter/Envs/mqtt/lib/python3.10/site-packages/argcomplete/bash_completion.d/_python-argcomplete"
# End added by argcomplete

Note: Make sure ~/.bashrc enables running /usr/share/bash-completion/bash_completion which runs ~/.bash_completion.

# snippet of ~/.bashrc

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

If you don't want to enable /usr/share/bash-completion/bash_completion, you will need to add ~/.bash_completion into .bashrc as follows.

# enable python argcomplete global completion feature in local user
if [ -f ~/.bash_completion ] && ! shopt -oq posix; then
    . ~/.bash_completion
fi

Step 3: Try It Out

$ python awshelper.py ec2.<TAB>
ec2.create  ec2.ls