forked from python-cmd2/cmd2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathargparse_completion.py
118 lines (98 loc) · 4.43 KB
/
argparse_completion.py
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
#!/usr/bin/env python
# coding=utf-8
"""
A simple example demonstrating how to integrate tab completion with argparse-based commands.
"""
import argparse
from typing import (
Dict,
List,
)
from cmd2 import (
Cmd,
Cmd2ArgumentParser,
CompletionError,
CompletionItem,
ansi,
with_argparser,
)
# Data source for argparse.choices
food_item_strs = ['Pizza', 'Ham', 'Ham Sandwich', 'Potato']
class ArgparseCompletion(Cmd):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.sport_item_strs = ['Bat', 'Basket', 'Basketball', 'Football', 'Space Ball']
def choices_provider(self) -> List[str]:
"""A choices provider is useful when the choice list is based on instance data of your application"""
return self.sport_item_strs
def choices_completion_error(self) -> List[str]:
"""
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 self.sport_item_strs
raise CompletionError("debug must be true")
# noinspection PyMethodMayBeStatic
def choices_completion_item(self) -> List[CompletionItem]:
"""Return CompletionItem instead of strings. These give more context to what's being tab completed."""
fancy_item = "These things can\ncontain newlines and\n"
fancy_item += ansi.style("styled text!!", fg=ansi.Fg.LIGHT_YELLOW, underline=True)
items = {1: "My item", 2: "Another item", 3: "Yet another item", 4: fancy_item}
return [CompletionItem(item_id, description) for item_id, description in items.items()]
# noinspection PyMethodMayBeStatic
def choices_arg_tokens(self, arg_tokens: Dict[str, List[str]]) -> List[str]:
"""
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 values
# Parser for example command
example_parser = Cmd2ArgumentParser(
description="Command demonstrating tab completion with argparse\n" "Notice 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 returning CompletionItems instead of strings
example_parser.add_argument(
'--completion_item',
choices_provider=choices_completion_item,
metavar="ITEM_ID",
descriptive_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())