Skip to content

AutoComplete Design

Tristan Morgan edited this page Jun 24, 2021 · 2 revisions

Autocomplete needs to parse the current command line and try to work out what would be the expected next input. in Bash the command line is passed as an environment variable COMP_LINE. the current cursor position is passed as COMP_POINT, but the application is also is called with the current argument and the previous one.

awskeyring console personal --no-token --path cloudformation 
             |        |       |         |         |
      sub_command(1)  |       |         |         |
                   param(2)   |         |         |
                           flag(3)    flag(3)     |
                                             flag-values(4)
  1. The sub command, should be from the list_commands method, if a partial command is entered we try to match the prefix and if only one command matches we assume that is what the user wanted. (list_commands)
  2. Params, if we can identify the sub command we take the names of the paramters to search for accounts, roles and even commands. (param_type)
  3. flags, some commands take optional flags and some of those have (list_arguments)...
  4. flag-values. some flags require a value (list_paths, list_browsers)

Example completions

In the following examples we can assume the COMP_POINT is the length of COMP_LINE.

Example 1

awskeyring con
             |
      sub_command

To complete commands we are called with the following:

AwskeyringCommand.autocomplete('con', 'awskeyring')
ENV['COMP_LINE'] = 'awskeyring con'

Because this is the first parameter it is assumed to need completion from the list of commands.

Example 2

awskeyring console perso
            |        |
      sub_command    |
                   param

this results in the call:

AwskeyringCommand.autocomplete('perso', 'console')
ENV['COMP_LINE'] = 'awskeyring console perso'

This scenario is where we can identify the sub command 'console' and from its signature it requires an 'account' so we return a list of accounts to complete "personal"

Example 3

awskeyring console personal --no
             |        |       |
      sub_command     |       |
                   param      |
                            flag

leading to:

AwskeyringCommand.autocomplete('--no', 'personal')
ENV['COMP_LINE'] = 'awskeyring console personal --no'

Here, we have identified the sub_command and it only has one parameter so we must now be looking for optional flags, so we lookup the different flags available for this sub_command and complete it with '--no-token'.

Example 4

awskeyring console personal --no-token --path clou 
             |        |       |         |       |
      sub_command(1)  |       |         |       |
                   param(2)   |         |       |
                           flag       flag      |
                                           flag-values

Finally:

AwskeyringCommand.autocomplete('clou', '--path')
ENV['COMP_LINE'] = 'awskeyring console personal --no-token --path clou'

In this one the previous field was a flag '--path' and that requires a path (in the aws console) to open so the list of paths is returned, filtered by the prefix given.