summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd2/argparse_custom.py2
-rw-r--r--cmd2/cmd2.py9
-rw-r--r--cmd2/parsing.py13
-rw-r--r--tests/test_history.py2
-rw-r--r--tests/test_parsing.py2
5 files changed, 15 insertions, 13 deletions
diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py
index 1cdb7840..5d8e76ef 100644
--- a/cmd2/argparse_custom.py
+++ b/cmd2/argparse_custom.py
@@ -74,7 +74,7 @@ Tab Completion:
completer_method
This is exactly like completer_function, but the function needs to be an instance method of a cmd2-based class.
When AutoCompleter calls the method, it will pass the app instance as the self argument. cmd2 provides
- a few completer methods for convenience (e.g. path_complete, delimiter_complete)
+ a few completer methods for convenience (e.g., path_complete, delimiter_complete)
Example:
This adds file-path completion to an argument
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index b8e5d9d2..2c37635d 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -397,9 +397,6 @@ class Cmd(cmd.Cmd):
self._py_history = []
self.pyscript_name = 'app'
- if shortcuts is None:
- shortcuts = constants.DEFAULT_SHORTCUTS
- shortcuts = sorted(shortcuts.items(), reverse=True)
self.statement_parser = StatementParser(allow_redirection=allow_redirection,
terminators=terminators,
multiline_commands=multiline_commands,
@@ -472,7 +469,7 @@ class Cmd(cmd.Cmd):
# If natural sorting is preferred, then set this to NATURAL_SORT_KEY.
# cmd2 uses this key for sorting:
# command and category names
- # alias, macro, and settable names
+ # alias, macro, settable, and shortcut names
# tab completion results when self.matches_sorted is False
self.default_sort_key = ALPHABETICAL_SORT_KEY
@@ -2816,7 +2813,9 @@ class Cmd(cmd.Cmd):
@with_argparser(ArgParser())
def do_shortcuts(self, _: argparse.Namespace) -> None:
"""List available shortcuts"""
- result = "\n".join('%s: %s' % (sc[0], sc[1]) for sc in sorted(self.statement_parser.shortcuts))
+ # Sort the shortcut tuples by name
+ sorted_shortcuts = sorted(self.statement_parser.shortcuts, key=lambda x: self.default_sort_key(x[0]))
+ result = "\n".join('{}: {}'.format(sc[0], sc[1]) for sc in sorted_shortcuts)
self.poutput("Shortcuts for other commands:\n{}".format(result))
@with_argparser(ArgParser(epilog=INTERNAL_COMMAND_EPILOG))
diff --git a/cmd2/parsing.py b/cmd2/parsing.py
index 2e94516a..dbfabc80 100644
--- a/cmd2/parsing.py
+++ b/cmd2/parsing.py
@@ -249,7 +249,7 @@ class StatementParser:
terminators: Optional[Iterable[str]] = None,
multiline_commands: Optional[Iterable[str]] = None,
aliases: Optional[Dict[str, str]] = None,
- shortcuts: Optional[Iterable[Tuple[str, str]]] = None) -> None:
+ shortcuts: Optional[Dict[str, str]] = None) -> None:
"""Initialize an instance of StatementParser.
The following will get converted to an immutable tuple before storing internally:
@@ -261,7 +261,7 @@ class StatementParser:
:param terminators: iterable containing strings which should terminate multiline commands
:param multiline_commands: iterable containing the names of commands that accept multiline input
:param aliases: dictionary containing aliases
- :param shortcuts: an iterable of tuples with each tuple containing the shortcut and the expansion
+ :param shortcuts: dictionary containing shortcuts
"""
self.allow_redirection = allow_redirection
if terminators is None:
@@ -276,10 +276,13 @@ class StatementParser:
self.aliases = dict()
else:
self.aliases = aliases
+
if shortcuts is None:
- self.shortcuts = tuple()
- else:
- self.shortcuts = tuple(shortcuts)
+ shortcuts = constants.DEFAULT_SHORTCUTS
+
+ # Sort the shortcuts in descending order by name length because the longest match
+ # should take precedence. (e.g., @@file should match '@@' and not '@'.
+ self.shortcuts = tuple(sorted(shortcuts.items(), key=lambda x: len(x[0]), reverse=True))
# commands have to be a word, so make a regular expression
# that matches the first word in the line. This regex has three
diff --git a/tests/test_history.py b/tests/test_history.py
index add93ea6..88f38172 100644
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -276,7 +276,7 @@ def parser():
'l': '!ls -al',
'anothermultiline': 'multiline',
'fake': 'run_pyscript'},
- shortcuts=[('?', 'help'), ('!', 'shell')]
+ shortcuts={'?': 'help', '!': 'shell'}
)
return parser
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index 13a535c0..a629d9fa 100644
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -21,7 +21,7 @@ def parser():
'l': '!ls -al',
'anothermultiline': 'multiline',
'fake': 'run_pyscript'},
- shortcuts=[('?', 'help'), ('!', 'shell')]
+ shortcuts={'?': 'help', '!': 'shell'}
)
return parser