diff options
-rw-r--r-- | CHANGELOG.md | 11 | ||||
-rwxr-xr-x | README.md | 4 | ||||
-rwxr-xr-x | cmd2.py | 16 | ||||
-rw-r--r-- | docs/freefeatures.rst | 17 | ||||
-rw-r--r-- | docs/settingchanges.rst | 3 | ||||
-rwxr-xr-x | examples/example.py | 1 | ||||
-rw-r--r-- | examples/transcripts/exampleSession.txt | 1 | ||||
-rw-r--r-- | examples/transcripts/transcript_regex.txt | 1 | ||||
-rwxr-xr-x | setup.py | 2 | ||||
-rw-r--r-- | tests/conftest.py | 4 | ||||
-rw-r--r-- | tests/scripts/postcmds.txt | 1 | ||||
-rw-r--r-- | tests/scripts/precmds.txt | 1 | ||||
-rw-r--r-- | tests/test_cmd2.py | 56 | ||||
-rw-r--r-- | tests/test_parsing.py | 6 | ||||
-rw-r--r-- | tests/test_transcript.py | 3 | ||||
-rw-r--r-- | tests/transcripts/regex_set.txt | 1 |
16 files changed, 20 insertions, 108 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bdb2714..b774a1f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ * Fixed outdated help text for the **edit** command * Fixed outdated [remove_unused.py](https://github.com/python-cmd2/cmd2/blob/master/examples/remove_unused.py) * Enhancements - * Added support for sub-menus. + * Added support for sub-menus. * See [submenus.py](https://github.com/python-cmd2/cmd2/blob/master/examples/submenus.py) for an example of how to use it * Added option for persistent readline history * See [persistent_history.py](https://github.com/python-cmd2/cmd2/blob/master/examples/persistent_history.py) for an example @@ -14,7 +14,12 @@ * Improved PyPI packaging by including unit tests, examples, and docs in the tarball * Improved documentation to make it more obvious that **poutput()** should be used instead of **print()** * ``exclude_from_help`` and ``excludeFromHistory`` are now instance instead of class attributes - + * Added flag and index based tab completion helper functions + * See [tab_completion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/tab_completion.py) +* Attributes Removed + * ``abbrev`` - Removed support for abbreviated commands + * Good tab completion makes this unnecessary + ## 0.8.0 (February 1, 2018) * Bug Fixes * Fixed unit tests on Python 3.7 due to changes in how re.escape() behaves in Python 3.7 @@ -28,7 +33,7 @@ * **with_argparser_and_unknown_args** decorator for argparse-based argument parsing, but allows unknown args * **do_*** commands get two arguments, the output of argparse.parse_known_args() * See the [Argument Processing](http://cmd2.readthedocs.io/en/latest/argument_processing.html) section of the documentation for more information on these decorators - * Alternatively, see the [argparse_example.py](https://github.com/python-cmd2/cmd2/blob/master/examples/argparse_example.py) + * Alternatively, see the [argparse_example.py](https://github.com/python-cmd2/cmd2/blob/master/examples/argparse_example.py) and [arg_print.py](https://github.com/python-cmd2/cmd2/blob/master/examples/arg_print.py) examples * Added support for Argpasre sub-commands when using the **with_argument_parser** or **with_argparser_and_unknown_args** decorators * See [subcommands.py](https://github.com/python-cmd2/cmd2/blob/master/examples/subcommands.py) for an example of how to use subcommands @@ -26,7 +26,7 @@ Main Features - Redirect command output to file with `>`, `>>`; input from file with `<` - Bare `>`, `>>` with no filename send output to paste buffer (clipboard) - `py` enters interactive Python console (opt-in `ipy` for IPython console) -- Multi-line, case-insensitive, and abbreviated commands +- Multi-line and case-insensitive commands - Special-character command shortcuts (beyond cmd's `@` and `!`) - Settable environment parameters - Parsing commands with arguments using `argparse`, including support for sub-commands @@ -171,7 +171,6 @@ class CmdLineApp(Cmd): MUMBLE_LAST = ['right?'] def __init__(self): - self.abbrev = True self.multilineCommands = ['orate'] self.maxrepeats = 3 @@ -248,7 +247,6 @@ example/transcript_regex.txt: # The regex for editor will match whatever program you use. # regexes on prompts just make the trailing space obvious (Cmd) set -abbrev: True colors: /(True|False)/ continuation_prompt: >/ / debug: False @@ -995,7 +995,7 @@ class Cmd(cmd.Cmd): commentGrammars = pyparsing.Or([pyparsing.pythonStyleComment, pyparsing.cStyleComment]) commentInProgress = pyparsing.Literal('/*') + pyparsing.SkipTo(pyparsing.stringEnd ^ '*/') legalChars = u'!#$%.:?@_-' + pyparsing.alphanums + pyparsing.alphas8bit - multilineCommands = [] # NOTE: Multiline commands can never be abbreviated, even if abbrev is True + multilineCommands = [] prefixParser = pyparsing.Empty() redirector = '>' # for sending output to file shortcuts = {'?': 'help', '!': 'shell', '@': 'load', '@@': '_relative_load'} @@ -1008,7 +1008,6 @@ class Cmd(cmd.Cmd): reserved_words = [] # Attributes which ARE dynamically settable at runtime - abbrev = False # Abbreviated commands recognized colors = (platform.system() != 'Windows') continuation_prompt = '> ' debug = False @@ -1029,8 +1028,7 @@ class Cmd(cmd.Cmd): # To make an attribute settable with the "do_set" command, add it to this ... # This starts out as a dictionary but gets converted to an OrderedDict sorted alphabetically by key - settable = {'abbrev': 'Accept abbreviated commands', - 'colors': 'Colorized output (*nix only)', + settable = {'colors': 'Colorized output (*nix only)', 'continuation_prompt': 'On 2nd+ line of input', 'debug': 'Show full error stack on error', 'echo': 'Echo command issued into output', @@ -1076,7 +1074,7 @@ class Cmd(cmd.Cmd): # Commands to exclude from the help menu or history command self.exclude_from_help = ['do_eof', 'do_eos', 'do__relative_load'] - self.excludeFromHistory = '''history histor histo hist his hi h edit edi ed e eof eo eos'''.split() + self.excludeFromHistory = '''history edit eof eos'''.split() self._finalize_app_parameters() @@ -1664,9 +1662,6 @@ class Cmd(cmd.Cmd): def _func_named(self, arg): """Gets the method name associated with a given command. - If self.abbrev is False, it is always just looks for do_arg. However, if self.abbrev is True, - it allows abbreviated command names and looks for any commands which start with do_arg. - :param arg: str - command to look up method name which implements it :return: str - method name which implements the given command """ @@ -1674,11 +1669,6 @@ class Cmd(cmd.Cmd): target = 'do_' + arg if target in dir(self): result = target - else: - if self.abbrev: # accept shortened versions of commands - funcs = [func for func in self.keywords if func.startswith(arg) and func not in self.multilineCommands] - if len(funcs) == 1: - result = 'do_' + funcs[0] return result def onecmd(self, line): diff --git a/docs/freefeatures.rst b/docs/freefeatures.rst index a439db56..f0918bba 100644 --- a/docs/freefeatures.rst +++ b/docs/freefeatures.rst @@ -271,23 +271,6 @@ Quitting the application It's trivial, but it's one less thing for you to remember. -Abbreviated commands -==================== - -``cmd2`` apps will accept shortened command names -so long as there is no ambiguity if the ``abbrev`` settable parameter is set to ``True``. -Thus, if ``do_divide`` is defined, then ``divid``, ``div``, -or even ``d`` will suffice, so long as there are -no other commands defined beginning with *divid*, -*div*, or *d*. - -This behavior is disabled by default, but can be turned on with ``app.abbrev`` (see :ref:`parameters`) - -.. warning:: - - Due to the way the parsing logic works for multiline commands, abbreviations - will not be accepted for multiline commands. - Misc. pre-defined commands ========================== diff --git a/docs/settingchanges.rst b/docs/settingchanges.rst index 2b9f9a86..3e48fe24 100644 --- a/docs/settingchanges.rst +++ b/docs/settingchanges.rst @@ -116,7 +116,6 @@ comments, is viewable from within a running application with:: (Cmd) set --long - abbrev: False # Accept abbreviated commands colors: True # Colorized output (*nix only) continuation_prompt: > # On 2nd+ line of input debug: False # Show full error stack on error @@ -130,5 +129,5 @@ with:: Any of these user-settable parameters can be set while running your app with the ``set`` command like so:: - set abbrev True + set colors False diff --git a/examples/example.py b/examples/example.py index c66f0e60..94ca7693 100755 --- a/examples/example.py +++ b/examples/example.py @@ -27,7 +27,6 @@ class CmdLineApp(Cmd): MUMBLE_LAST = ['right?'] def __init__(self): - self.abbrev = True self.multilineCommands = ['orate'] self.maxrepeats = 3 diff --git a/examples/transcripts/exampleSession.txt b/examples/transcripts/exampleSession.txt index 840bee60..1d1b3b79 100644 --- a/examples/transcripts/exampleSession.txt +++ b/examples/transcripts/exampleSession.txt @@ -3,7 +3,6 @@ # The regex for editor will match whatever program you use. # regexes on prompts just make the trailing space obvious (Cmd) set -abbrev: False colors: /(True|False)/ continuation_prompt: >/ / debug: False diff --git a/examples/transcripts/transcript_regex.txt b/examples/transcripts/transcript_regex.txt index 7d017dee..adf4d77e 100644 --- a/examples/transcripts/transcript_regex.txt +++ b/examples/transcripts/transcript_regex.txt @@ -3,7 +3,6 @@ # The regex for editor will match whatever program you use. # regexes on prompts just make the trailing space obvious (Cmd) set -abbrev: True colors: /(True|False)/ continuation_prompt: >/ / debug: False @@ -26,7 +26,7 @@ Main features: - Redirect command output to file with `>`, `>>`; input from file with `<` - Bare `>`, `>>` with no filename send output to paste buffer (clipboard) - `py` enters interactive Python console (opt-in `ipy` for IPython console) - - Multi-line, case-insensitive, and abbreviated commands + - Multi-line and case-insensitive commands - Special-character command shortcuts (beyond cmd's `@` and `!`) - Settable environment parameters - Parsing commands with arguments using `argparse`, including support for sub-commands diff --git a/tests/conftest.py b/tests/conftest.py index 319e54fe..5ee5dd58 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -53,8 +53,7 @@ expect_colors = True if sys.platform.startswith('win'): expect_colors = False # Output from the show command with default settings -SHOW_TXT = """abbrev: False -colors: {} +SHOW_TXT = """colors: {} continuation_prompt: > debug: False echo: False @@ -71,7 +70,6 @@ if expect_colors: else: color_str = 'False' SHOW_LONG = """ -abbrev: False # Accept abbreviated commands colors: {} # Colorized output (*nix only) continuation_prompt: > # On 2nd+ line of input debug: False # Show full error stack on error diff --git a/tests/scripts/postcmds.txt b/tests/scripts/postcmds.txt index 760bcdf5..2b478b57 100644 --- a/tests/scripts/postcmds.txt +++ b/tests/scripts/postcmds.txt @@ -1,2 +1 @@ -set abbrev off set colors off diff --git a/tests/scripts/precmds.txt b/tests/scripts/precmds.txt index d8857e92..d0b27fb6 100644 --- a/tests/scripts/precmds.txt +++ b/tests/scripts/precmds.txt @@ -1,2 +1 @@ -set abbrev on set colors on diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index ee9c1fc3..67f4c9c6 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -470,12 +470,10 @@ def test_load_nested_loads(base_app, request): expected = """ %s _relative_load precmds.txt -set abbrev on set colors on help shortcuts _relative_load postcmds.txt -set abbrev off set colors off""" % initial_load assert run_cmd(base_app, 'history -s') == normalize(expected) @@ -494,12 +492,10 @@ def test_base_runcmds_plus_hooks(base_app, request): 'load ' + postfilepath]) expected = """ load %s -set abbrev on set colors on help shortcuts load %s -set abbrev off set colors off""" % (prefilepath, postfilepath) assert run_cmd(base_app, 'history -s') == normalize(expected) @@ -1275,49 +1271,6 @@ def test_cmdresult(cmdresult_app): assert cmdresult_app._last_result == cmd2.CmdResult('', arg) -@pytest.fixture -def abbrev_app(): - app = cmd2.Cmd() - app.abbrev = True - app.stdout = StdOut() - return app - -def test_exclude_from_history(abbrev_app, monkeypatch): - # Run all variants of run - run_cmd(abbrev_app, 'run') - run_cmd(abbrev_app, 'ru') - run_cmd(abbrev_app, 'r') - - # Mock out the os.system call so we don't actually open an editor - m = mock.MagicMock(name='system') - monkeypatch.setattr("os.system", m) - - # Run all variants of edit - run_cmd(abbrev_app, 'edit') - run_cmd(abbrev_app, 'edi') - run_cmd(abbrev_app, 'ed') - - # Run all variants of history - run_cmd(abbrev_app, 'history') - run_cmd(abbrev_app, 'histor') - run_cmd(abbrev_app, 'histo') - run_cmd(abbrev_app, 'hist') - run_cmd(abbrev_app, 'his') - run_cmd(abbrev_app, 'hi') - - # Verify that the history is empty - out = run_cmd(abbrev_app, 'history') - assert out == [] - - # Now run a command which isn't excluded from the history - run_cmd(abbrev_app, 'help') - # And verify we have a history now ... - out = run_cmd(abbrev_app, 'history') - expected = normalize("""-------------------------[1] -help""") - assert out == expected - - def test_is_text_file_bad_input(base_app): # Test with a non-existent file file_is_valid = base_app.is_text_file('does_not_exist.txt') @@ -1421,7 +1374,7 @@ def test_pseudo_raw_input_piped_rawinput_true_echo_true(capsys): app, out = piped_rawinput_true(capsys, True, command) out = out.splitlines() assert out[0] == '{}{}'.format(app.prompt, command) - assert out[1] == 'abbrev: False' + assert out[1] == 'colors: True' # using the decorator puts the original function at six.moves.input # back when this method returns @@ -1431,7 +1384,7 @@ def test_pseudo_raw_input_piped_rawinput_true_echo_false(capsys): command = 'set' app, out = piped_rawinput_true(capsys, False, command) firstline = out.splitlines()[0] - assert firstline == 'abbrev: False' + assert firstline == 'colors: True' assert not '{}{}'.format(app.prompt, command) in out # the next helper function and two tests check for piped @@ -1442,7 +1395,6 @@ def piped_rawinput_false(capsys, echo, command): app = cmd2.Cmd(stdin=fakein) app.use_rawinput = False app.echo = echo - app.abbrev = False app._cmdloop() out, err = capsys.readouterr() return (app, out) @@ -1452,13 +1404,13 @@ def test_pseudo_raw_input_piped_rawinput_false_echo_true(capsys): app, out = piped_rawinput_false(capsys, True, command) out = out.splitlines() assert out[0] == '{}{}'.format(app.prompt, command) - assert out[1] == 'abbrev: False' + assert out[1] == 'colors: True' def test_pseudo_raw_input_piped_rawinput_false_echo_false(capsys): command = 'set' app, out = piped_rawinput_false(capsys, False, command) firstline = out.splitlines()[0] - assert firstline == 'abbrev: False' + assert firstline == 'colors: True' assert not '{}{}'.format(app.prompt, command) in out # diff --git a/tests/test_parsing.py b/tests/test_parsing.py index 5a741b57..c7abf07c 100644 --- a/tests/test_parsing.py +++ b/tests/test_parsing.py @@ -326,12 +326,6 @@ def test_parse_multiline_ignores_terminators_in_comments(parser): assert results.terminator[0] == '\n' assert results.terminator[1] == '\n' -def test_parse_abbreviated_multiline_not_allowed(parser): - line = 'multilin command\n' - results = parser.parseString(line) - assert results.command == 'multilin' - assert results.multilineCommand == '' - # Unicode support is only present in cmd2 for Python 3 @pytest.mark.skipif(sys.version_info < (3,0), reason="cmd2 unicode support requires python3") def test_parse_command_with_unicode_args(parser): diff --git a/tests/test_transcript.py b/tests/test_transcript.py index 41322341..43b7a72c 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -27,7 +27,6 @@ class CmdLineApp(Cmd): MUMBLE_LAST = ['right?'] def __init__(self, *args, **kwargs): - self.abbrev = True self.multilineCommands = ['orate'] self.maxrepeats = 3 self.redirector = '->' @@ -159,7 +158,7 @@ OODNIGHT, GRACIEGAY OODNIGHT, GRACIEGAY OODNIGHT, GRACIEGAY OODNIGHT, GRACIEGAY -(Cmd) hi +(Cmd) history -------------------------[1] help -------------------------[2] diff --git a/tests/transcripts/regex_set.txt b/tests/transcripts/regex_set.txt index 6c12b4cb..bf88c294 100644 --- a/tests/transcripts/regex_set.txt +++ b/tests/transcripts/regex_set.txt @@ -4,7 +4,6 @@ # Regexes on prompts just make the trailing space obvious (Cmd) set -abbrev: True colors: /(True|False)/ continuation_prompt: >/ / debug: False |