Tab Completion
The library provides generic tab completion functionality. This can either be
automatic (for example, parameters of type bool
) or provided by the business
logic of the application. Consider the sample program below:
import recline
from recline.arg_types.choices import Choices
from recline.formatters.table_formatter import TableFormat
# A stand-in for a database or some other form of persistence
ORDERS = {}
MENU = ['black bean', 'choirizo', 'steak']
def get_customers():
return list(ORDERS.keys())
def get_order_types():
return [o["type"] for o in ORDERS.values()]
@recline.command(name="order burrito")
def order_burrito(
customer_name: str,
type: Choices.define(available_choices=MENU),
grilled: bool = True,
) -> None:
"""Place an order for a delicious burrito
Arguments:
cusomter_name: The name of the customer who is ordering
type: Describes the fillings of the burrito
grilled: If the burrito should be browned on the grill
"""
ORDERS[customer_name] = {"type": type, "grilled": grilled}
print("One order for a %s burrito, coming up!" % type)
@recline.command(name="show orders")
def show_orders(
customer_name: Choices.define(available_choices=get_customers) = None,
type: Choices.define(available_choices=get_order_types) = None,
grilled: bool = None,
) -> TableFormat:
"""List all of the orders that match the given query
Arguments:
cusomter_name: The name of the customer who made the order
type: The type of burrito that was ordered
grilled: List only burritos with this grilling status
Returns:
A list of all orders matching the query
"""
matching_orders = []
for customer, order in ORDERS.items():
if customer_name and customer != customer_name:
continue
if type and type != order["type"]:
continue
if grilled is not None and grilled != order["grilled"]:
continue
matching_orders.append({"customer": customer, "type": order["type"], "grilled": order["grilled"]})
return matching_orders
recline.relax(prompt="tacos galore> ")
Note
In the examples below, I will put the string [Tab]
in the output to show
where the [Tab]
key was typed. The characters are not literally displayed
when running the program.
Command Completion
The first level of tab completion is command completion. This means that the user
can press the [Tab]
key in order to show the list of commands the matches the
current input on the command line. For example, if there was nothing typed yet, the
program above would display this:
tacos galore> [Tab]
? debug exit
fg help man
order burrito q quit
show orders
tacos galore>
Here, all of the available commands, including the builtin commands are shown. If
the user started typing the command they wanted to execute and then hit [Tab]
,
it might look like this:
tacos galore> ord[Tab]
tacos galore> order burrito
Hard to show here, but there would not be two lines on the display. The library
knows that the only command that matches the prefix ord
is order burrito
and completes the rest of the words.
Argument Completion
Continuing from the last section, if the user presses [Tab]
immediately,
they will be shown a list of available arguments:
tacos galore> order burrito [Tab]
-customer_name -grilled -type
tacos galore> order burrito -
Here, we can see that the list is shown starting on the next line and then the
library reprinted what was already typed and started filling in the common prefix
that all of the arguments have in common (in this case, just a -
). If there
had been more of a common prefix, it would have included that as well.
Knowing that they want to fill in the type field, the user types a t
and presses
[Tab]
again:
tacos galore> order burrito -t[Tab]
tacos galore> order burrito -type
Again, this would not appear on two lines on the display.
Value Completion
Continuing from the last section, the user wants to complete an order so they
press [Tab]
once more to determine which types are available:
tacos galore> order burrito -type [Tab]
black\ bean choirizo steak
tacos galore> order burrito -type ch[Tab]
tacos galore> order burrito -type chorizo -cust[Tab]
tacos galore> order burrito -type chorizo -customer_name Suzane
One order for a choirizo burrito, coming up!
tacos galore>
After finishing our order, we can see the current orders by again pressing [Tab]
as we navigate the show command:
tacos galore> sh[Tab]
tacos galore> show orders [Tab]
-customer_name -grilled -type
tacos galore> show orders -cu[Tab]
tacos galore> show orders -customer_name [Tab]
tacos galore> show orders -customer_name Suzane
+----------+----------+---------+
| Customer | Type | Grilled |
+----------+----------+---------+
| Suzane | choirizo | True |
+----------+----------+---------+
tacos galore>
Since we pressed [Tab]
to find the possible choices for customer name and there
was only one, the library filled it in for us. If there was more than one value
available, it would have showed us choices like this:
tacos galore> order burrito -type choirizo -customer_name Sue
One order for a choirizo burrito, coming up!
tacos galore> show orders -customer_name [Tab]
Sue Suzane
tacos galore> show orders -customer_name Su
We can see that this time, since they share a prefix, the library filled in the common parts of the name and waits for the user to give more uniqueness.