diff options
author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-07-07 21:45:52 -0400 |
---|---|---|
committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-07-07 21:45:52 -0400 |
commit | bb2dd69bd04f5dccff9474c018eb6b6eea74c6af (patch) | |
tree | 543f626a84ac96d97c478e4e1af185ce07831908 /cmd2 | |
parent | f8db8b766540920de6c85a26a6740170455b9354 (diff) | |
download | cmd2-git-bb2dd69bd04f5dccff9474c018eb6b6eea74c6af.tar.gz |
Moved all custom argparse classes intended for normal development to argparse_custom.py.
Lazy loading AutoCompleter in cmd2 instance methods to allow argparse_completer.py to import
cmd2.Cmd class. This Architecture makes more sense because AutoCompleter depends on cmd2.Cmd.
Diffstat (limited to 'cmd2')
-rw-r--r-- | cmd2/__init__.py | 1 | ||||
-rw-r--r-- | cmd2/argparse_completer.py | 55 | ||||
-rw-r--r-- | cmd2/argparse_custom.py | 56 | ||||
-rw-r--r-- | cmd2/cmd2.py | 6 |
4 files changed, 62 insertions, 56 deletions
diff --git a/cmd2/__init__.py b/cmd2/__init__.py index d3c92636..3b149601 100644 --- a/cmd2/__init__.py +++ b/cmd2/__init__.py @@ -11,6 +11,7 @@ except DistributionNotFound: pass from .ansi import style +from .argparse_custom import Cmd2ArgParser, CompletionItem from .cmd2 import Cmd, Statement, EmptyStatement, categorize from .cmd2 import with_argument_list, with_argparser, with_argparser_and_unknown_args, with_category from .constants import DEFAULT_SHORTCUTS diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py index 1a8dd473..1a156f8f 100644 --- a/cmd2/argparse_completer.py +++ b/cmd2/argparse_completer.py @@ -62,66 +62,17 @@ import argparse import shutil from typing import List, Union +from . import cmd2 from . import utils from .ansi import ansi_safe_wcswidth from .argparse_custom import ATTR_SUPPRESS_TAB_HINT, ATTR_DESCRIPTIVE_COMPLETION_HEADER, ATTR_NARGS_RANGE -from .argparse_custom import ChoicesCallable, ATTR_CHOICES_CALLABLE +from .argparse_custom import ChoicesCallable, CompletionItem, ATTR_CHOICES_CALLABLE from .rl_utils import rl_force_redisplay # If no descriptive header is supplied, then this will be used instead DEFAULT_DESCRIPTIVE_HEADER = 'Description' -class CompletionItem(str): - """ - Completion item with descriptive text attached - - Returning this instead of a regular string for completion results will signal the - autocompleter to output the completions results in a table of completion tokens - with descriptions instead of just a table of tokens. - - For example, you'd see this: - TOKEN Description - MY_TOKEN Info about my token - SOME_TOKEN Info about some token - YET_ANOTHER Yet more info - - Instead of this: - TOKEN_ID SOME_TOKEN YET_ANOTHER - - This is especially useful if you want to complete ID numbers in a more - user-friendly manner. For example, you can provide this: - - ITEM_ID Item Name - 1 My item - 2 Another item - 3 Yet another item - - Instead of this: - 1 2 3 - - Example: - token = 1 - token_description = "My Item" - completion_item = CompletionItem(token, token_description) - """ - def __new__(cls, value: object, *args, **kwargs) -> str: - return super().__new__(cls, value) - - # noinspection PyUnusedLocal - def __init__(self, value: object, desc: str = '', *args, **kwargs) -> None: - """ - CompletionItem Initializer - - :param value: the value being tab completed - :param desc: description text to display - :param args: args for str __init__ - :param kwargs: kwargs for str __init__ - """ - super().__init__(*args, **kwargs) - self.description = desc - - # noinspection PyProtectedMember def is_potential_flag(token: str, parser: argparse.ArgumentParser) -> bool: """Determine if a token looks like a potential flag. Based on argparse._parse_optional().""" @@ -171,7 +122,7 @@ class AutoCompleter(object): self.needed = False self.variable = False - def __init__(self, parser: argparse.ArgumentParser, cmd2_app, *, + def __init__(self, parser: argparse.ArgumentParser, cmd2_app: cmd2.Cmd, *, token_start_index: int = 1) -> None: """ Create an AutoCompleter diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py index b05ca6ed..5e3ed7f5 100644 --- a/cmd2/argparse_custom.py +++ b/cmd2/argparse_custom.py @@ -26,6 +26,56 @@ ATTR_SUPPRESS_TAB_HINT = 'suppress_tab_hint' ATTR_DESCRIPTIVE_COMPLETION_HEADER = 'desc_completion_header' +class CompletionItem(str): + """ + Completion item with descriptive text attached + + Returning this instead of a regular string for completion results will signal the + autocompleter to output the completions results in a table of completion tokens + with descriptions instead of just a table of tokens. + + For example, you'd see this: + TOKEN Description + MY_TOKEN Info about my token + SOME_TOKEN Info about some token + YET_ANOTHER Yet more info + + Instead of this: + TOKEN_ID SOME_TOKEN YET_ANOTHER + + This is especially useful if you want to complete ID numbers in a more + user-friendly manner. For example, you can provide this: + + ITEM_ID Item Name + 1 My item + 2 Another item + 3 Yet another item + + Instead of this: + 1 2 3 + + Example: + token = 1 + token_description = "My Item" + completion_item = CompletionItem(token, token_description) + """ + def __new__(cls, value: object, *args, **kwargs) -> str: + return super().__new__(cls, value) + + # noinspection PyUnusedLocal + def __init__(self, value: object, desc: str = '', *args, **kwargs) -> None: + """ + CompletionItem Initializer + + :param value: the value being tab completed + :param desc: description text to display + :param args: args for str __init__ + :param kwargs: kwargs for str __init__ + """ + super().__init__(*args, **kwargs) + self.description = desc + + class ChoicesCallable: """ Enables using a callable as the choices provider for an argparse argument. @@ -77,8 +127,10 @@ def _add_argument_wrapper(self, *args, :param choices_method: cmd2-app method that provides choices for this argument :param completer_function: tab-completion function that provides choices for this argument :param completer_method: cmd2-app tab-completion method that provides choices for this argument - :param suppress_tab_hint: when AutoCompleter has no choices to show during tab completion, it displays the current - argument's help text as a hint. Set this to True to suppress the hint. Defaults to False. + :param suppress_tab_hint: when AutoCompleter has no results to show during tab completion, it displays the current + argument's help text as a hint. Set this to True to suppress the hint. If this argument's + help text is set to argparse.SUPPRESS, then tab hints will not display regardless of the + value passed for suppress_tab_hint. Defaults to False. :param descriptive_header: if the provided choices are CompletionItems, then this header will display during tab completion. Defaults to None. diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index bfda6ae2..0d14d5ad 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -46,8 +46,7 @@ from . import ansi from . import constants from . import plugin from . import utils -from .argparse_completer import AutoCompleter, CompletionItem -from .argparse_custom import Cmd2ArgParser +from .argparse_custom import Cmd2ArgParser, CompletionItem from .clipboard import can_clip, get_paste_buffer, write_to_paste_buffer from .history import History, HistoryItem from .parsing import StatementParser, Statement, Macro, MacroArg, shlex_split @@ -1582,6 +1581,7 @@ class Cmd(cmd.Cmd): def _autocomplete_default(self, text: str, line: str, begidx: int, endidx: int, argparser: argparse.ArgumentParser) -> List[str]: """Default completion function for argparse commands""" + from .argparse_completer import AutoCompleter completer = AutoCompleter(argparser, self) tokens, _ = self.tokens_for_completion(line, begidx, endidx) return completer.complete_command(tokens, text, line, begidx, endidx) @@ -2643,6 +2643,7 @@ class Cmd(cmd.Cmd): # Check if this is a command with an argparse function func = self.cmd_func(command) if func and hasattr(func, 'argparser'): + from .argparse_completer import AutoCompleter completer = AutoCompleter(getattr(func, 'argparser'), self) matches = completer.complete_command_help(tokens[cmd_index:], text, line, begidx, endidx) @@ -2673,6 +2674,7 @@ class Cmd(cmd.Cmd): # If the command function uses argparse, then use argparse's help if func and hasattr(func, 'argparser'): + from .argparse_completer import AutoCompleter completer = AutoCompleter(getattr(func, 'argparser'), self) tokens = [args.command] + args.subcommand self.poutput(completer.format_help(tokens)) |