summaryrefslogtreecommitdiff
path: root/examples/modular_commands_main.py
diff options
context:
space:
mode:
authorEric Lin <anselor@gmail.com>2020-06-11 18:00:07 -0400
committeranselor <anselor@gmail.com>2020-08-04 13:38:08 -0400
commite1087b8f29341397b09e9a0722a77c025ab20d23 (patch)
treee63eaa1e117973f1e9870c3b187438ae2e5a735e /examples/modular_commands_main.py
parent787c95251e38ef80821f395b6147982876977081 (diff)
downloadcmd2-git-e1087b8f29341397b09e9a0722a77c025ab20d23.tar.gz
Initial implementation of modular command loading
Issue #943 New class CommandSet can be used to tag a class as a command class. If the constructor is simple, the object will automatically be instantiated and loaded. New register_command decorator to tag any arbitrary function as a command.
Diffstat (limited to 'examples/modular_commands_main.py')
-rw-r--r--examples/modular_commands_main.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/examples/modular_commands_main.py b/examples/modular_commands_main.py
new file mode 100644
index 00000000..93dc79ea
--- /dev/null
+++ b/examples/modular_commands_main.py
@@ -0,0 +1,127 @@
+#!/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, CompletionItem, with_argparser
+from cmd2.utils import CompletionError, basic_complete
+from modular_commands.commandset_basic import BasicCompletionCommandSet # noqa: F401
+from modular_commands.commandset_custominit import CustomInitCommandSet
+
+# Data source for argparse.choices
+food_item_strs = ['Pizza', 'Ham', 'Ham Sandwich', 'Potato']
+
+
+def choices_function() -> List[str]:
+ """Choices functions are useful when the choice list is dynamically generated (e.g. from data in a database)"""
+ return ['a', 'dynamic', 'list', 'goes', 'here']
+
+
+def completer_function(text: str, line: str, begidx: int, endidx: int) -> List[str]:
+ """
+ A tab completion function not dependent on instance data. Since custom tab completion operations commonly
+ need to modify cmd2's instance variables related to tab completion, it will be rare to need a completer
+ function. completer_method should be used in those cases.
+ """
+ match_against = ['a', 'dynamic', 'list', 'goes', 'here']
+ return basic_complete(text, line, begidx, endidx, match_against)
+
+
+def choices_completion_item() -> List[CompletionItem]:
+ """Return CompletionItem instead of strings. These give more context to what's being tab completed."""
+ items = \
+ {
+ 1: "My item",
+ 2: "Another item",
+ 3: "Yet another item"
+ }
+ return [CompletionItem(item_id, description) for item_id, description in items.items()]
+
+
+def choices_arg_tokens(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_function flag has appeared
+ values = ['choices_function', 'flag']
+ if 'choices_function' in arg_tokens:
+ values.append('is {}'.format(arg_tokens['choices_function'][0]))
+ else:
+ values.append('not supplied')
+ return values
+
+
+class WithCommandSets(Cmd):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.sport_item_strs = ['Bat', 'Basket', 'Basketball', 'Football', 'Space Ball']
+
+ def choices_method(self) -> List[str]:
+ """Choices methods are 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")
+
+ # 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 function and choices method
+ example_parser.add_argument('--choices_function', choices_function=choices_function,
+ help="tab complete using a choices_function")
+ example_parser.add_argument('--choices_method', choices_method=choices_method,
+ help="tab complete using a choices_method")
+
+ # Tab complete using a completer function and completer method
+ example_parser.add_argument('--completer_function', completer_function=completer_function,
+ help="tab complete using a completer_function")
+ example_parser.add_argument('--completer_method', completer_method=Cmd.path_complete,
+ help="tab complete using a completer_method")
+
+ # Demonstrate raising a CompletionError while tab completing
+ example_parser.add_argument('--completion_error', choices_method=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_function=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_function=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
+
+ print("Starting")
+ command_sets = [CustomInitCommandSet('First argument', 'Second argument')]
+ app = WithCommandSets(command_sets=command_sets)
+ sys.exit(app.cmdloop())