Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

88%
+13 −0
Q&A How do I support tab completion in a python CLI program?

It depends. Do you want to have autocomplete on the shell the program runs in, or do you want the program to intercept the TAB key and do the autocomplete by itself? Shell autocomplete If you'r...

posted 2y ago by hkotsubo‭  ·  edited 2y ago by hkotsubo‭

Answer
#3: Post edited by user avatar hkotsubo‭ · 2021-10-26T20:49:20Z (over 2 years ago)
  • It depends. Do you want to have autocomplete on the shell the program runs in, or do you want the program to intercept the TAB key and do the autocomplete by itself?
  • ---
  • # Shell autocomplete
  • If you're running your program in a Linux shell, and want to autocomplete in the shell's command line (such as `script.py <TAB>`), then it must be configured in the shell itself. In this case you have to provide a custom autocomplete script, such as [this](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash).
  • To provide a simpler version, let's suppose my Python file is `script.py` and I want to add autocomplete in Bash. I'd create a bash script like this:
  • ```bash
  • #!/bin/bash
  • _script_options() {
  • local cur prev opts
  • COMPREPLY=()
  • cur="${COMP_WORDS[COMP_CWORD]}"
  • prev="${COMP_WORDS[COMP_CWORD-1]}"
  • opts="--help -a -b --some-option"
  • if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
  • COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  • return 0
  • fi
  • case "${prev}" in
  • -a) # list only CSV files
  • local files=$(ls *.csv)
  • COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
  • ;;
  • # other options has no further autocomplete
  • esac
  • }
  • ```
  • Then you could copy this script to `/etc/bash_completion.d/`, and in your `.bashrc` file just add a line to register it:
  • ```bash
  • complete -F _script_options script.py
  • ```
  • Now open a new terminal, and when you type `script.py <TAB>` it'll use the logic provided by the `_script_options` function. There's a nice explanation [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html), but for short:
  • - `COMPREPLY` is the array from which Bash reads the possible completions
  • - `COMP_WORDS` is an array with the words of the current command line, and `COMP_CWORD` is an index into `${COMP_WORDS}` of the word containing the current cursor position
  • - hence, `cur` contains the current word of the command line, while `prev` contains the previous word
  • - `opts` contains the default list of options for the script
  • If I type `script.py <TAB>`, it'll enter the `if` (because we're in the first word), and it'll show the options in the `opts` variable (using the command `compgen` to generate the list from the word list contained in `opts`).
  • If I type `script.py -a <TAB>`, it'll not enter the `if`, because the current word is the second (an empty one, as I just pressed `TAB`). As the previous word (contained in `prev`) is `-a`, it'll enter the first `case` option. And in that case, I show only the CVS files in the current directory (the list of file names was obtained using `ls` command).
  • You can customize this to contain any logic you want (check again [the Git's script](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash) to see how complicated it can be). But the basic idea is to use `COMP_WORDS` and the other variables described [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html) to know what's already typed, and set `COMPREPLY` with the respective options.
  • <sup>For Windows shell, I don't know how to do it.</sup>
  • ---
  • # Inside the program
  • If you want the Python program itself to interpret the TAB key and show the autocomplete options, one alternative is to use the [`cmd` module](https://docs.python.org/3/library/cmd.html). Quick example:
  • ```python
  • from cmd import Cmd
  • class CustomCommand(Cmd):
  • def __init__(self):
  • super().__init__()
  • self.prompt = 'CustomCommand> '
  • self.command1_options = [ 'a', 'b', 'some-option', 'someother-option' ]
  • def do_command1(self, line):
  • """
  • This docstring will be displayed if you type "help command1"
  • """
  • # do whatever the command needs to do ("line" contains the whole command that was typed)
  • ...
  • def complete_command1(self, text, line, start_index, end_index):
  • if text: # if I already started typing the option, filter the existing options
  • return [
  • option for option in self.command1_options
  • if option.startswith(text)
  • ]
  • else:
  • return self.command1_options
  • my_cmd = CustomCommand()
  • my_cmd.cmdloop()
  • ```
  • If I run the code above, it'll show a prompt like this:
  • ```bash
  • $ python teste.py
  • CustomCommand>
  • ```
  • The `CustomCommand> ` &nbsp; prompt is the string I've set in `self.prompt`. If I type `com<TAB>`, it'll autocomplete with the `command1` command:
  • ```bash
  • CustomCommand> command1
  • ```
  • Now if I type `command1 <TAB><TAB>` (note the space after "command1"), it'll call the `complete_command1` method and use the array returned by it to know the autocomplete options. The `text` argument contains whatever is typed so far (ex: if I type `command1 some<TAB><TAB>`, inside the `complete_command1` method the `text` argument will have the value `some` and it'll return a list containing only "some-option" and "someother-option").
  • After typing the command and pressing ENTER, it'll run the `do_command1` method. Basically, you create `do_foo` methods to execute `foo` commands, and `complete_foo` methods to provide the autocomplete options for those commands.
  • As it's Python code, you can put whatever logic you want inside the methods (ex: use `glob` or `os` modules to list only specific files, etc). All the methods receive the `line` argument containing the whole command that was typed.
  • It depends. Do you want to have autocomplete on the shell the program runs in, or do you want the program to intercept the TAB key and do the autocomplete by itself?
  • ---
  • # Shell autocomplete
  • If you're running your program in a Linux shell, and want to autocomplete in the shell's command line (such as `script.py <TAB>`), then it must be configured in the shell itself. In this case you have to provide a custom autocomplete script, such as [this](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash).
  • To provide a simpler version, let's suppose my Python file is `script.py` and I want to add autocomplete in Bash. I'd create a bash script like this:
  • ```bash
  • #!/bin/bash
  • _script_options() {
  • local cur prev opts
  • COMPREPLY=()
  • cur="${COMP_WORDS[COMP_CWORD]}"
  • prev="${COMP_WORDS[COMP_CWORD-1]}"
  • opts="--help -a -b --some-option"
  • if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
  • COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  • return 0
  • fi
  • case "${prev}" in
  • -a) # list only CSV files
  • local files=$(ls *.csv)
  • COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
  • ;;
  • # other options has no further autocomplete
  • esac
  • }
  • ```
  • Then you could copy this script to `/etc/bash_completion.d/`, and in your `.bashrc` file just add a line to register it:
  • ```bash
  • complete -F _script_options script.py
  • ```
  • Now open a new terminal, and when you type `script.py <TAB>` it'll use the logic provided by the `_script_options` function. There's a nice explanation [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html), but for short:
  • - `COMPREPLY` is the array from which Bash reads the possible completions
  • - `COMP_WORDS` is an array with the words of the current command line, and `COMP_CWORD` is an index into `${COMP_WORDS}` of the word containing the current cursor position
  • - hence, `cur` contains the current word of the command line, while `prev` contains the previous word
  • - `opts` contains the default list of options for the script
  • If I type `script.py <TAB>`, it'll enter the `if` (because we're in the first word), and it'll show the options in the `opts` variable (using the command `compgen` to generate the list from the word list contained in `opts`).
  • If I type `script.py -a <TAB>`, it'll not enter the `if`, because the current word is the second (an empty one, as I just pressed `TAB`). As the previous word (contained in `prev`) is `-a`, it'll enter the first `case` option. And in that case, I show only the CSV files in the current directory (the list of file names was obtained using `ls` command).
  • You can customize this to contain any logic you want (check again [the Git's script](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash) to see how complicated it can be). But the basic idea is to use `COMP_WORDS` and the other variables described [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html) to know what's already typed, and set `COMPREPLY` with the respective options.
  • <sup>For Windows shell, I don't know how to do it.</sup>
  • ---
  • # Inside the program
  • If you want the Python program itself to interpret the TAB key and show the autocomplete options, one alternative is to use the [`cmd` module](https://docs.python.org/3/library/cmd.html). Quick example:
  • ```python
  • from cmd import Cmd
  • class CustomCommand(Cmd):
  • def __init__(self):
  • super().__init__()
  • self.prompt = 'CustomCommand> '
  • self.command1_options = [ 'a', 'b', 'some-option', 'someother-option' ]
  • def do_command1(self, line):
  • """
  • This docstring will be displayed if you type "help command1"
  • """
  • # do whatever the command needs to do ("line" contains the whole command that was typed)
  • ...
  • def complete_command1(self, text, line, start_index, end_index):
  • if text: # if I already started typing the option, filter the existing options
  • return [
  • option for option in self.command1_options
  • if option.startswith(text)
  • ]
  • else:
  • return self.command1_options
  • my_cmd = CustomCommand()
  • my_cmd.cmdloop()
  • ```
  • If I run the code above, it'll show a prompt like this:
  • ```bash
  • $ python teste.py
  • CustomCommand>
  • ```
  • The `CustomCommand> ` &nbsp; prompt is the string I've set in `self.prompt`. If I type `com<TAB>`, it'll autocomplete with the `command1` command:
  • ```bash
  • CustomCommand> command1
  • ```
  • Now if I type `command1 <TAB><TAB>` (note the space after "command1"), it'll call the `complete_command1` method and use the array returned by it to know the autocomplete options. The `text` argument contains whatever is typed so far (ex: if I type `command1 some<TAB><TAB>`, inside the `complete_command1` method the `text` argument will have the value `some` and it'll return a list containing only "some-option" and "someother-option").
  • After typing the command and pressing ENTER, it'll run the `do_command1` method. Basically, you create `do_foo` methods to execute `foo` commands, and `complete_foo` methods to provide the autocomplete options for those commands.
  • As it's Python code, you can put whatever logic you want inside the methods (ex: use `glob` or `os` modules to list only specific files, etc). All the methods receive the `line` argument containing the whole command that was typed.
#2: Post edited by user avatar hkotsubo‭ · 2021-10-26T19:30:18Z (over 2 years ago)
  • It depends. Do you want to have autocomplete on the shell the program runs in, or do you want the program to intercept the TAB key and do the autocomplete by itself?
  • ---
  • # Shell autocomplete
  • If you're running your program in a Linux shell, and want to autocomplete in the shell's command line (such as `script.py <TAB>`), then it must be configured in the shell itself. In this case you have to provide a custom autocomplete script, such as [this](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash).
  • To provide a simpler version, let's suppose my Python file is `script.py` and I want to add autocomplete in Bash. I'd create a bash script like this:
  • ```bash
  • #!/bin/bash
  • _script_options() {
  • local cur prev opts
  • COMPREPLY=()
  • cur="${COMP_WORDS[COMP_CWORD]}"
  • prev="${COMP_WORDS[COMP_CWORD-1]}"
  • opts="--help -a -b --some-option"
  • if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
  • COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  • return 0
  • fi
  • case "${prev}" in
  • -a) # list only CSV files
  • local files=$(ls *.csv)
  • COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
  • ;;
  • # other options has no further autocomplete
  • esac
  • }
  • ```
  • Then you could copy this script to `/etc/bash_completion.d/`, and in your `.bashrc` file just add a line to register it:
  • ```bash
  • complete -F _script_options script.py
  • ```
  • Now open a new terminal, and when you type `script.py <TAB>` it'll use the logic provided by the `_script_options` function. There's a nice explanation [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html), but for short:
  • - `COMPREPLY` is the array from which Bash reads the possible completions
  • - `COMP_WORDS` is an array with the words of the current command line, and `COMP_CWORD` is an index into `${COMP_WORDS}` of the word containing the current cursor position
  • - hence, `cur` contains the current word of the command line, while `prev` contains the previous word
  • - `opts` contains the default list of options for the script
  • If I type `script.py <TAB>`, it'll enter the `if` (because we're in the first word), and it'll show the options in the `opts` variable (using the command `compgen` to generate the list from the word list contained in `opts`).
  • If I type `script.py -a <TAB>`, it'll not enter the `if`, because the current word is the second (an empty one, as I just pressed `TAB`). As the previous word (contained in `prev`) is `-a`, it'll enter the first `case` option. And in that case, I show only the CVS files in the current directory (the list of file names was obtained using `ls` command).
  • You can customize this to contain any logic you want (check again [the Git's script](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash) to see how complicated it can be). But the basic idea is to use `COMP_WORDS` and the other variables described [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html) to know what's already typed, and set `COMPREPLY` with the respective options.
  • <sup>For Windows shell, I don't know how to do it.</sup>
  • ---
  • # Inside the program
  • If you want the Python program itself to interpret the TAB key and show the autocomplete options, one alternative is to use the [`cmd` module](https://docs.python.org/3/library/cmd.html). Quick example:
  • ```python
  • from cmd import Cmd
  • class CustomCommand(Cmd):
  • def __init__(self):
  • super().__init__()
  • self.prompt = 'CustomCommand> '
  • self.command1_options = [ 'a', 'b', 'some-option', 'someother-option' ]
  • def do_command1(self, line):
  • """
  • This docstring will be displayed if you type "help command1"
  • """
  • # do whatever the command needs to do ("line" contains the whole command that was typed)
  • ...
  • def complete_command1(self, text, line, start_index, end_index):
  • if text: # if I already started typing the option, filter the existing options
  • return [
  • option for option in self.command1_options
  • if option.startswith(text)
  • ]
  • else:
  • return self.command1_options
  • my_cmd = CustomCommand()
  • my_cmd.cmdloop()
  • ```
  • If I run the code above, it'll show a prompt like this:
  • ```bash
  • $ python teste.py
  • CustomCommand>
  • ```
  • The `CustomCommand> ` &nbsp; prompt is the string I've set in `self.prompt`. If I type `com<TAB>`, it'll autocomplete with the `command1` command:
  • ```bash
  • CustomCommand> command1
  • ```
  • Now if I type `command1 <TAB><TAB>` (note the space after "command1"), it'll call the `complete_command1` method and use the array returned by it to know the autocomplete options. The `text` argument contains whatever is typed so far (ex: `command1 som<TAB><TAB>`, `text` will contain `som` and it'll show only some-option and someother-option).
  • After typing the command and pressing ENTER, it'll run the `do_command1` method. Basically, you create `do_foo` methods to execute `foo` commands, and `complete_foo` methods to provide the autocomplete options for those commands.
  • As it's Python code, you can put whatever logic you want inside the methods (ex: use `glob` or `os` modules to list only specific files, etc).
  • It depends. Do you want to have autocomplete on the shell the program runs in, or do you want the program to intercept the TAB key and do the autocomplete by itself?
  • ---
  • # Shell autocomplete
  • If you're running your program in a Linux shell, and want to autocomplete in the shell's command line (such as `script.py <TAB>`), then it must be configured in the shell itself. In this case you have to provide a custom autocomplete script, such as [this](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash).
  • To provide a simpler version, let's suppose my Python file is `script.py` and I want to add autocomplete in Bash. I'd create a bash script like this:
  • ```bash
  • #!/bin/bash
  • _script_options() {
  • local cur prev opts
  • COMPREPLY=()
  • cur="${COMP_WORDS[COMP_CWORD]}"
  • prev="${COMP_WORDS[COMP_CWORD-1]}"
  • opts="--help -a -b --some-option"
  • if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
  • COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
  • return 0
  • fi
  • case "${prev}" in
  • -a) # list only CSV files
  • local files=$(ls *.csv)
  • COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
  • ;;
  • # other options has no further autocomplete
  • esac
  • }
  • ```
  • Then you could copy this script to `/etc/bash_completion.d/`, and in your `.bashrc` file just add a line to register it:
  • ```bash
  • complete -F _script_options script.py
  • ```
  • Now open a new terminal, and when you type `script.py <TAB>` it'll use the logic provided by the `_script_options` function. There's a nice explanation [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html), but for short:
  • - `COMPREPLY` is the array from which Bash reads the possible completions
  • - `COMP_WORDS` is an array with the words of the current command line, and `COMP_CWORD` is an index into `${COMP_WORDS}` of the word containing the current cursor position
  • - hence, `cur` contains the current word of the command line, while `prev` contains the previous word
  • - `opts` contains the default list of options for the script
  • If I type `script.py <TAB>`, it'll enter the `if` (because we're in the first word), and it'll show the options in the `opts` variable (using the command `compgen` to generate the list from the word list contained in `opts`).
  • If I type `script.py -a <TAB>`, it'll not enter the `if`, because the current word is the second (an empty one, as I just pressed `TAB`). As the previous word (contained in `prev`) is `-a`, it'll enter the first `case` option. And in that case, I show only the CVS files in the current directory (the list of file names was obtained using `ls` command).
  • You can customize this to contain any logic you want (check again [the Git's script](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash) to see how complicated it can be). But the basic idea is to use `COMP_WORDS` and the other variables described [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html) to know what's already typed, and set `COMPREPLY` with the respective options.
  • <sup>For Windows shell, I don't know how to do it.</sup>
  • ---
  • # Inside the program
  • If you want the Python program itself to interpret the TAB key and show the autocomplete options, one alternative is to use the [`cmd` module](https://docs.python.org/3/library/cmd.html). Quick example:
  • ```python
  • from cmd import Cmd
  • class CustomCommand(Cmd):
  • def __init__(self):
  • super().__init__()
  • self.prompt = 'CustomCommand> '
  • self.command1_options = [ 'a', 'b', 'some-option', 'someother-option' ]
  • def do_command1(self, line):
  • """
  • This docstring will be displayed if you type "help command1"
  • """
  • # do whatever the command needs to do ("line" contains the whole command that was typed)
  • ...
  • def complete_command1(self, text, line, start_index, end_index):
  • if text: # if I already started typing the option, filter the existing options
  • return [
  • option for option in self.command1_options
  • if option.startswith(text)
  • ]
  • else:
  • return self.command1_options
  • my_cmd = CustomCommand()
  • my_cmd.cmdloop()
  • ```
  • If I run the code above, it'll show a prompt like this:
  • ```bash
  • $ python teste.py
  • CustomCommand>
  • ```
  • The `CustomCommand> ` &nbsp; prompt is the string I've set in `self.prompt`. If I type `com<TAB>`, it'll autocomplete with the `command1` command:
  • ```bash
  • CustomCommand> command1
  • ```
  • Now if I type `command1 <TAB><TAB>` (note the space after "command1"), it'll call the `complete_command1` method and use the array returned by it to know the autocomplete options. The `text` argument contains whatever is typed so far (ex: if I type `command1 some<TAB><TAB>`, inside the `complete_command1` method the `text` argument will have the value `some` and it'll return a list containing only "some-option" and "someother-option").
  • After typing the command and pressing ENTER, it'll run the `do_command1` method. Basically, you create `do_foo` methods to execute `foo` commands, and `complete_foo` methods to provide the autocomplete options for those commands.
  • As it's Python code, you can put whatever logic you want inside the methods (ex: use `glob` or `os` modules to list only specific files, etc). All the methods receive the `line` argument containing the whole command that was typed.
#1: Initial revision by user avatar hkotsubo‭ · 2021-10-26T18:57:44Z (over 2 years ago)
It depends. Do you want to have autocomplete on the shell the program runs in, or do you want the program to intercept the TAB key and do the autocomplete by itself?

---
# Shell autocomplete

If you're running your program in a Linux shell, and want to autocomplete in the shell's command line (such as `script.py <TAB>`), then it must be configured in the shell itself. In this case you have to provide a custom autocomplete script, such as [this](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash).

To provide a simpler version, let's suppose my Python file is `script.py` and I want to add autocomplete in Bash. I'd create a bash script like this:

```bash
#!/bin/bash

_script_options() {
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--help -a -b --some-option"

    if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi

    case "${prev}" in
        -a) # list only CSV files
            local files=$(ls *.csv)
            COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
        ;;
        # other options has no further autocomplete
    esac
}
```

Then you could copy this script to `/etc/bash_completion.d/`, and in your `.bashrc` file just add a line to register it:

```bash
complete -F _script_options script.py
```

Now open a new terminal, and when you type `script.py <TAB>` it'll use the logic provided by the `_script_options` function. There's a nice explanation [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html), but for short:

- `COMPREPLY` is the array from which Bash reads the possible completions
- `COMP_WORDS` is an array with the words of the current command line, and `COMP_CWORD` is an index into `${COMP_WORDS}` of the word containing the current cursor position
    - hence, `cur` contains the current word of the command line, while `prev` contains the previous word
- `opts` contains the default list of options for the script

If I type `script.py <TAB>`, it'll enter the `if` (because we're in the first word), and it'll show the options in the `opts` variable (using the command `compgen` to generate the list from the word list contained in `opts`).

If I type `script.py -a <TAB>`, it'll not enter the `if`, because the current word is the second (an empty one, as I just pressed `TAB`). As the previous word (contained in `prev`) is `-a`, it'll enter the first `case` option. And in that case, I show only the CVS files in the current directory (the list of file names was obtained using `ls` command).

You can customize this to contain any logic you want (check again [the Git's script](https://github.com/git/git/blob/master/contrib/completion/git-completion.bash) to see how complicated it can be). But the basic idea is to use `COMP_WORDS` and the other variables described [here](https://devmanual.gentoo.org/tasks-reference/completion/index.html) to know what's already typed, and set `COMPREPLY` with the respective options.

<sup>For Windows shell, I don't know how to do it.</sup>

---
# Inside the program

If you want the Python program itself to interpret the TAB key and show the autocomplete options, one alternative is to use the [`cmd` module](https://docs.python.org/3/library/cmd.html). Quick example:

```python
from cmd import Cmd

class CustomCommand(Cmd):
    def __init__(self):
        super().__init__()
        self.prompt = 'CustomCommand> '
        self.command1_options = [ 'a', 'b', 'some-option', 'someother-option' ]

    def do_command1(self, line):
        """
        This docstring will be displayed if you type "help command1"
        """
        # do whatever the command needs to do ("line" contains the whole command that was typed)
        ...

    def complete_command1(self, text, line, start_index, end_index):
        if text: # if I already started typing the option, filter the existing options
            return [
                option for option in self.command1_options
                if option.startswith(text)
            ]
        else:
            return self.command1_options


my_cmd = CustomCommand()
my_cmd.cmdloop()
```

If I run the code above, it'll show a prompt like this:

```bash
$ python teste.py
CustomCommand> 
```

The `CustomCommand> `  &nbsp; prompt is the string I've set in `self.prompt`. If I type `com<TAB>`, it'll autocomplete with the `command1` command:

```bash
CustomCommand> command1
```

Now if I type `command1 <TAB><TAB>` (note the space after "command1"), it'll call the `complete_command1` method and use the array returned by it to know the autocomplete options. The `text` argument contains whatever is typed so far (ex: `command1 som<TAB><TAB>`, `text` will contain `som` and it'll show only some-option and someother-option).

After typing the command and pressing ENTER, it'll run the `do_command1` method. Basically, you create `do_foo` methods to execute `foo` commands, and `complete_foo` methods to provide the autocomplete options for those commands.

As it's Python code, you can put whatever logic you want inside the methods (ex: use `glob` or `os` modules to list only specific files, etc).