summaryrefslogtreecommitdiff
path: root/cmd2/cmd2.py
diff options
context:
space:
mode:
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r--cmd2/cmd2.py76
1 files changed, 45 insertions, 31 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 610ce4a3..aaa45af6 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -51,6 +51,7 @@ from .decorators import with_argparser, as_subcommand_to
from .exceptions import (
CommandSetRegistrationError,
Cmd2ShlexError,
+ CompletionError,
EmbeddedConsoleExit,
EmptyStatement,
RedirectionError,
@@ -59,7 +60,7 @@ from .exceptions import (
from .history import History, HistoryItem
from .parsing import Macro, MacroArg, Statement, StatementParser, shlex_split
from .rl_utils import RlType, rl_get_point, rl_make_safe_prompt, rl_set_prompt, rl_type, rl_warning, vt100_support
-from .utils import CompletionError, get_defining_class, Settable
+from .utils import get_defining_class, Settable
# Set up readline
if rl_type == RlType.NONE: # pragma: no cover
@@ -1042,6 +1043,21 @@ class Cmd(cmd.Cmd):
return tokens, raw_tokens
+ # noinspection PyMethodMayBeStatic, PyUnusedLocal
+ def basic_complete(self, text: str, line: str, begidx: int, endidx: int, match_against: Iterable) -> List[str]:
+ """
+ Basic tab completion function that matches against a list of strings without considering line contents
+ or cursor position. The args required by this function are defined in the header of Python's cmd.py.
+
+ :param text: the string prefix we are attempting to match (all matches must begin with it)
+ :param line: the current input line with leading whitespace removed
+ :param begidx: the beginning index of the prefix text
+ :param endidx: the ending index of the prefix text
+ :param match_against: the strings being matched against
+ :return: a list of possible tab completions
+ """
+ return [cur_match for cur_match in match_against if cur_match.startswith(text)]
+
def delimiter_complete(self, text: str, line: str, begidx: int, endidx: int,
match_against: Iterable, delimiter: str) -> List[str]:
"""
@@ -1076,7 +1092,7 @@ class Cmd(cmd.Cmd):
:param delimiter: what delimits each portion of the matches (ex: paths are delimited by a slash)
:return: a list of possible tab completions
"""
- matches = utils.basic_complete(text, line, begidx, endidx, match_against)
+ matches = self.basic_complete(text, line, begidx, endidx, match_against)
# Display only the portion of the match that's being completed based on delimiter
if matches:
@@ -1137,7 +1153,7 @@ class Cmd(cmd.Cmd):
# Perform tab completion using an Iterable
if isinstance(match_against, Iterable):
- completions_matches = utils.basic_complete(text, line, begidx, endidx, match_against)
+ completions_matches = self.basic_complete(text, line, begidx, endidx, match_against)
# Perform tab completion using a function
elif callable(match_against):
@@ -1181,7 +1197,7 @@ class Cmd(cmd.Cmd):
# Perform tab completion using a Iterable
if isinstance(match_against, Iterable):
- matches = utils.basic_complete(text, line, begidx, endidx, match_against)
+ matches = self.basic_complete(text, line, begidx, endidx, match_against)
# Perform tab completion using a function
elif callable(match_against):
@@ -1765,7 +1781,7 @@ class Cmd(cmd.Cmd):
# Otherwise complete token against anything a user can run
else:
match_against = self._get_commands_aliases_and_macros_for_completion()
- self.completion_matches = utils.basic_complete(text, line, begidx, endidx, match_against)
+ self.completion_matches = self.basic_complete(text, line, begidx, endidx, match_against)
# If we have one result and we are at the end of the line, then add a space if allowed
if len(self.completion_matches) == 1 and endidx == len(line) and self.allow_appended_space:
@@ -2695,9 +2711,9 @@ class Cmd(cmd.Cmd):
epilog=alias_create_epilog)
alias_create_parser.add_argument('name', help='name of this alias')
alias_create_parser.add_argument('command', help='what the alias resolves to',
- choices_method=_get_commands_aliases_and_macros_for_completion)
+ choices_provider=_get_commands_aliases_and_macros_for_completion)
alias_create_parser.add_argument('command_args', nargs=argparse.REMAINDER, help='arguments to pass to command',
- completer_method=path_complete)
+ completer=path_complete)
@as_subcommand_to('alias', 'create', alias_create_parser, help=alias_create_description.lower())
def _alias_create(self, args: argparse.Namespace) -> None:
@@ -2738,7 +2754,7 @@ class Cmd(cmd.Cmd):
alias_delete_parser = DEFAULT_ARGUMENT_PARSER(add_help=False, description=alias_delete_description)
alias_delete_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='alias(es) to delete',
- choices_method=_get_alias_completion_items, descriptive_header='Value')
+ choices_provider=_get_alias_completion_items, descriptive_header='Value')
alias_delete_parser.add_argument('-a', '--all', action='store_true', help="delete all aliases")
@as_subcommand_to('alias', 'delete', alias_delete_parser, help=alias_delete_help)
@@ -2766,7 +2782,7 @@ class Cmd(cmd.Cmd):
alias_list_parser = DEFAULT_ARGUMENT_PARSER(add_help=False, description=alias_list_description)
alias_list_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='alias(es) to list',
- choices_method=_get_alias_completion_items, descriptive_header='Value')
+ choices_provider=_get_alias_completion_items, descriptive_header='Value')
@as_subcommand_to('alias', 'list', alias_list_parser, help=alias_delete_help)
def _alias_list(self, args: argparse.Namespace) -> None:
@@ -2846,9 +2862,9 @@ class Cmd(cmd.Cmd):
epilog=macro_create_epilog)
macro_create_parser.add_argument('name', help='name of this macro')
macro_create_parser.add_argument('command', help='what the macro resolves to',
- choices_method=_get_commands_aliases_and_macros_for_completion)
+ choices_provider=_get_commands_aliases_and_macros_for_completion)
macro_create_parser.add_argument('command_args', nargs=argparse.REMAINDER,
- help='arguments to pass to command', completer_method=path_complete)
+ help='arguments to pass to command', completer=path_complete)
@as_subcommand_to('macro', 'create', macro_create_parser, help=macro_create_help)
def _macro_create(self, args: argparse.Namespace) -> None:
@@ -2935,7 +2951,7 @@ class Cmd(cmd.Cmd):
macro_delete_description = "Delete specified macros or all macros if --all is used"
macro_delete_parser = DEFAULT_ARGUMENT_PARSER(add_help=False, description=macro_delete_description)
macro_delete_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='macro(s) to delete',
- choices_method=_get_macro_completion_items, descriptive_header='Value')
+ choices_provider=_get_macro_completion_items, descriptive_header='Value')
macro_delete_parser.add_argument('-a', '--all', action='store_true', help="delete all macros")
@as_subcommand_to('macro', 'delete', macro_delete_parser, help=macro_delete_help)
@@ -2963,7 +2979,7 @@ class Cmd(cmd.Cmd):
macro_list_parser = DEFAULT_ARGUMENT_PARSER(add_help=False, description=macro_list_description)
macro_list_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='macro(s) to list',
- choices_method=_get_macro_completion_items, descriptive_header='Value')
+ choices_provider=_get_macro_completion_items, descriptive_header='Value')
@as_subcommand_to('macro', 'list', macro_list_parser, help=macro_list_help)
def _macro_list(self, args: argparse.Namespace) -> None:
@@ -2985,7 +3001,7 @@ class Cmd(cmd.Cmd):
topics = set(self.get_help_topics())
visible_commands = set(self.get_visible_commands())
strs_to_match = list(topics | visible_commands)
- return utils.basic_complete(text, line, begidx, endidx, strs_to_match)
+ return self.basic_complete(text, line, begidx, endidx, strs_to_match)
def complete_help_subcommands(self, text: str, line: str, begidx: int, endidx: int,
arg_tokens: Dict[str, List[str]]) -> List[str]:
@@ -3012,9 +3028,9 @@ class Cmd(cmd.Cmd):
help_parser = DEFAULT_ARGUMENT_PARSER(description="List available commands or provide "
"detailed help for a specific command")
help_parser.add_argument('command', nargs=argparse.OPTIONAL, help="command to retrieve help for",
- completer_method=complete_help_command)
+ completer=complete_help_command)
help_parser.add_argument('subcommands', nargs=argparse.REMAINDER, help="subcommand(s) to retrieve help for",
- completer_method=complete_help_subcommands)
+ completer=complete_help_subcommands)
help_parser.add_argument('-v', '--verbose', action='store_true',
help="print a list of all commands with descriptions of each")
@@ -3276,10 +3292,8 @@ class Cmd(cmd.Cmd):
arg_name = 'value'
settable_parser.add_argument(arg_name, metavar=arg_name, help=settable.description,
choices=settable.choices,
- choices_function=settable.choices_function,
- choices_method=settable.choices_method,
- completer_function=settable.completer_function,
- completer_method=settable.completer_method)
+ choices_provider=settable.choices_provider,
+ completer=settable.completer)
from .argparse_completer import ArgparseCompleter
completer = ArgparseCompleter(settable_parser, self)
@@ -3297,12 +3311,12 @@ class Cmd(cmd.Cmd):
set_parser_parent.add_argument('-v', '--verbose', action='store_true',
help='include description of parameters when viewing')
set_parser_parent.add_argument('param', nargs=argparse.OPTIONAL, help='parameter to set or view',
- choices_method=_get_settable_completion_items, descriptive_header='Description')
+ choices_provider=_get_settable_completion_items, descriptive_header='Description')
# Create the parser for the set command
set_parser = DEFAULT_ARGUMENT_PARSER(parents=[set_parser_parent])
set_parser.add_argument('value', nargs=argparse.OPTIONAL, help='new value for settable',
- completer_method=complete_set_value)
+ completer=complete_set_value)
# Preserve quotes so users can pass in quoted empty strings and flags (e.g. -h) as the value
@with_argparser(set_parser, preserve_quotes=True)
@@ -3363,9 +3377,9 @@ class Cmd(cmd.Cmd):
self.poutput(result_str)
shell_parser = DEFAULT_ARGUMENT_PARSER(description="Execute a command as if at the OS prompt")
- shell_parser.add_argument('command', help='the command to run', completer_method=shell_cmd_complete)
+ shell_parser.add_argument('command', help='the command to run', completer=shell_cmd_complete)
shell_parser.add_argument('command_args', nargs=argparse.REMAINDER, help='arguments to pass to command',
- completer_method=path_complete)
+ completer=path_complete)
# Preserve quotes since we are passing these strings to the shell
@with_argparser(shell_parser, preserve_quotes=True)
@@ -3656,9 +3670,9 @@ class Cmd(cmd.Cmd):
return py_bridge.stop
run_pyscript_parser = DEFAULT_ARGUMENT_PARSER(description="Run a Python script file inside the console")
- run_pyscript_parser.add_argument('script_path', help='path to the script file', completer_method=path_complete)
+ run_pyscript_parser.add_argument('script_path', help='path to the script file', completer=path_complete)
run_pyscript_parser.add_argument('script_arguments', nargs=argparse.REMAINDER,
- help='arguments to pass to script', completer_method=path_complete)
+ help='arguments to pass to script', completer=path_complete)
@with_argparser(run_pyscript_parser)
def do_run_pyscript(self, args: argparse.Namespace) -> Optional[bool]:
@@ -3752,10 +3766,10 @@ class Cmd(cmd.Cmd):
help='edit and then run selected history items')
history_action_group.add_argument('-o', '--output_file', metavar='FILE',
help='output commands to a script file, implies -s',
- completer_method=path_complete)
+ completer=path_complete)
history_action_group.add_argument('-t', '--transcript', metavar='TRANSCRIPT_FILE',
help='output commands and results to a transcript file,\nimplies -s',
- completer_method=path_complete)
+ completer=path_complete)
history_action_group.add_argument('-c', '--clear', action='store_true', help='clear all history')
history_format_group = history_parser.add_argument_group(title='formatting')
@@ -4062,7 +4076,7 @@ class Cmd(cmd.Cmd):
edit_parser = DEFAULT_ARGUMENT_PARSER(description=edit_description)
edit_parser.add_argument('file_path', nargs=argparse.OPTIONAL,
- help="optional path to a file to open in editor", completer_method=path_complete)
+ help="optional path to a file to open in editor", completer=path_complete)
@with_argparser(edit_parser)
def do_edit(self, args: argparse.Namespace) -> None:
@@ -4105,8 +4119,8 @@ class Cmd(cmd.Cmd):
run_script_parser = DEFAULT_ARGUMENT_PARSER(description=run_script_description)
run_script_parser.add_argument('-t', '--transcript', metavar='TRANSCRIPT_FILE',
help='record the output of the script as a transcript file',
- completer_method=path_complete)
- run_script_parser.add_argument('script_path', help="path to the script file", completer_method=path_complete)
+ completer=path_complete)
+ run_script_parser.add_argument('script_path', help="path to the script file", completer=path_complete)
@with_argparser(run_script_parser)
def do_run_script(self, args: argparse.Namespace) -> Optional[bool]: