-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathargparse_completion.py
More file actions
executable file
·135 lines (110 loc) · 4.94 KB
/
argparse_completion.py
File metadata and controls
executable file
·135 lines (110 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
"""A simple example demonstrating how to integrate tab completion with argparse-based commands."""
import argparse
import rich.box
from rich.style import Style
from rich.table import Table
from rich.text import Text
from cmd2 import (
Choices,
Cmd,
Cmd2ArgumentParser,
Cmd2Style,
Color,
CompletionError,
CompletionItem,
with_argparser,
)
# Data source for argparse.choices
food_item_strs = ['Pizza', 'Ham', 'Ham Sandwich', 'Potato']
class ArgparseCompletion(Cmd):
def __init__(self) -> None:
super().__init__(include_ipy=True)
self.sport_item_strs = ['Bat', 'Basket', 'Basketball', 'Football', 'Space Ball']
def choices_provider(self) -> Choices:
"""A choices provider is useful when the choice list is based on instance data of your application."""
return Choices.from_values(self.sport_item_strs)
def choices_completion_error(self) -> Choices:
"""CompletionErrors can be raised if an error occurs while tab completing.
Example use cases
- Reading a database to retrieve a tab completion data set failed
- A previous command line argument that determines the data set being completed is invalid
"""
if self.debug:
return Choices.from_values(self.sport_item_strs)
raise CompletionError("debug must be true")
def choices_completion_tables(self) -> Choices:
"""Return CompletionItems with completion tables. These give more context to what's being tab completed."""
fancy_item = Text.assemble(
"These things can\ncontain newlines and\n",
Text("styled text!!", style=Style(color=Color.BRIGHT_YELLOW, underline=True)),
)
table_item = Table(
"Left Column",
"Right Column",
box=rich.box.ROUNDED,
border_style=Cmd2Style.TABLE_BORDER,
)
table_item.add_row("Yes, it's true.", "CompletionItems can")
table_item.add_row("even display description", "data in tables!")
item_dict = {
1: "My item",
2: "Another item",
3: "Yet another item",
4: fancy_item,
5: table_item,
}
completion_items = [CompletionItem(item_id, table_row=[description]) for item_id, description in item_dict.items()]
return Choices(items=completion_items)
def choices_arg_tokens(self, arg_tokens: dict[str, list[str]]) -> Choices:
"""If a choices or completer function/method takes a value called arg_tokens, then it will be
passed a dictionary that maps the command line tokens up through the one being completed
to their argparse argument name. All values of the arg_tokens dictionary are lists, even if
a particular argument expects only 1 token.
"""
# Check if choices_provider flag has appeared
values = ['choices_provider', 'flag']
if 'choices_provider' in arg_tokens:
values.append('is {}'.format(arg_tokens['choices_provider'][0]))
else:
values.append('not supplied')
return Choices.from_values(values)
# Parser for example command
example_parser = Cmd2ArgumentParser(
description="Command demonstrating tab completion with argparse\nNotice even the flags of this command tab complete"
)
# Tab complete from a list using argparse choices. Set metavar if you don't
# want the entire choices list showing in the usage text for this command.
example_parser.add_argument('--choices', choices=food_item_strs, metavar="CHOICE", help="tab complete using choices")
# Tab complete from choices provided by a choices_provider
example_parser.add_argument(
'--choices_provider', choices_provider=choices_provider, help="tab complete using a choices_provider"
)
# Tab complete using a completer
example_parser.add_argument('--completer', completer=Cmd.path_complete, help="tab complete using a completer")
# Demonstrate raising a CompletionError while tab completing
example_parser.add_argument(
'--completion_error',
choices_provider=choices_completion_error,
help="raise a CompletionError while tab completing if debug is False",
)
# Demonstrate use of completion table
example_parser.add_argument(
'--completion_table',
choices_provider=choices_completion_tables,
metavar="ITEM_ID",
table_header=["Description"],
help="demonstrate use of CompletionItems",
)
# Demonstrate use of arg_tokens dictionary
example_parser.add_argument(
'--arg_tokens', choices_provider=choices_arg_tokens, help="demonstrate use of arg_tokens dictionary"
)
@with_argparser(example_parser)
def do_example(self, _: argparse.Namespace) -> None:
"""The example command."""
self.poutput("I do nothing")
if __name__ == '__main__':
import sys
app = ArgparseCompletion()
sys.exit(app.cmdloop())