diff options
-rw-r--r-- | CHANGELOG.md | 7 | ||||
-rwxr-xr-x | README.md | 1 | ||||
-rw-r--r-- | docs/settingchanges.rst | 53 | ||||
-rw-r--r-- | tests/test_cmd2.py | 23 |
4 files changed, 73 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 3015b793..e93f9ff9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,8 +21,11 @@ if the output is a pipe or a file the escape sequences are stripped * Always - output methods **never** strip ANSI escape sequences, regardless of the output destination * Never - output methods strip all ANSI escape sequences + * Added ``macro`` command to create macros, which are similar to aliases, but can take arguments when called + * ``alias`` is now an argparse command with subcommands to create, list, and delete aliases * Deprecations - * Deprecated the builtin ``cmd2`` suport for colors including ``Cmd.colorize()`` and ``Cmd._colorcodes`` + * Deprecated the builtin ``cmd2`` support for colors including ``Cmd.colorize()`` and ``Cmd._colorcodes`` + * `unalias` is no longer a command since ``alias delete`` replaced it * Deletions * The ``preparse``, ``postparsing_precmd``, and ``postparsing_postcmd`` methods *deprecated* in the previous release have been deleted @@ -139,7 +142,7 @@ * Fixed ``AttributeError`` on Windows when running a ``select`` command cause by **pyreadline** not implementing ``remove_history_item`` * Enhancements * Added warning about **libedit** variant of **readline** not being supported on macOS - * Added tab-completion of alias names in value filed of **alias** command + * Added tab-completion of alias names in value field of **alias** command * Enhanced the ``py`` console in the following ways * Added tab completion of Python identifiers instead of **cmd2** commands * Separated the ``py`` console history from the **cmd2** history @@ -31,6 +31,7 @@ Main Features - Multi-line commands - Special-character command shortcuts (beyond cmd's `?` and `!`) - Command aliasing similar to bash `alias` command +- Macros, which are similar to aliases, but can take arguments when called - Ability to load commands at startup from an initialization script - Settable environment parameters - Parsing commands with arguments using `argparse`, including support for sub-commands diff --git a/docs/settingchanges.rst b/docs/settingchanges.rst index e08b6026..25a671ab 100644 --- a/docs/settingchanges.rst +++ b/docs/settingchanges.rst @@ -50,17 +50,54 @@ To define more shortcuts, update the dict ``App.shortcuts`` with the Aliases ======= -In addition to shortcuts, ``cmd2`` provides a full alias feature via the ``alias`` command which is similar to the -``alias`` command in Bash. +In addition to shortcuts, ``cmd2`` provides a full alias feature via the ``alias`` command. Aliases work in a similar +fashion to aliases in the Bash shell. -The syntax to create an alias is ``alias <name> <value>``. ``value`` can contain spaces and does not need -to be quoted. Ex: ``alias ls !ls -lF`` +The syntax to create an alias is: ``alias create name command [args]``. -If ``alias`` is run without arguments, then a list of all aliases will be printed to stdout and are in the proper -``alias`` command syntax, meaning they can easily be reused. + Ex: ``alias create ls !ls -lF`` -The ``unalias`` is used to clear aliases. Using the ``-a`` flag will clear all aliases. Otherwise provide a list of -aliases to clear. Ex: ``unalias ls cd pwd`` will clear the aliases called ls, cd, and pwd. +For more details run: ``help alias create`` + +Use ``alias list`` to see all or some of your aliases. The output of this command displays your aliases using the same command that +was used to create them. Therefore you can place this output in a ``cmd2`` startup script to recreate your aliases each time +you start the application + + Ex: ``alias list`` + +For more details run: ``help alias list`` + +Use ``alias delete`` to remove aliases + +For more details run: ``help alias delete`` + +Macros +====== + +``cmd2`` provides a feature that is similar to aliases called macros. The major difference between macros and aliases +is that macros are intended to take arguments when called. These can be useful if you need to run a complex command +frequently with different arguments that appear in various parts of the command. + +Arguments are expressed when creating a macro using {#} notation where {1} means the first argument. + +The following creates a macro called my_macro that expects two arguments: + + macro create my_macro make_dinner -meat {1} -veggie {2} + +When the macro is called, the provided arguments are resolved and the assembled +command is run. For example: + + my_macro beef broccoli ---> make_dinner -meat beef -veggie broccoli + +For more details run: ``help macro create`` + +The macro command has ``list`` and ``delete`` subcommands that function identically to the alias subcommands of the +same name. Like aliases, macros can be created via a ``cmd2`` startup script to preserve them across application +sessions. + +For more details on listing macros run: ``help macro list`` + +For more details on deleting macros run: ``help macro delete`` Default to shell diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py index 5ee0d26b..707fce49 100644 --- a/tests/test_cmd2.py +++ b/tests/test_cmd2.py @@ -1992,9 +1992,19 @@ def test_macro_create_with_invalid_arg_num(base_app, capsys): out, err = capsys.readouterr() assert "Argument numbers must be greater than 0" in err +def test_macro_create_with_wrong_arg_count(base_app, capsys): + # Create the macro + out = run_cmd(base_app, 'macro create fake help {1} {2}') + assert out == normalize("Macro 'fake' created") + + # Run the macro + run_cmd(base_app, 'fake arg1') + out, err = capsys.readouterr() + assert "expects 2 argument(s)" in err + def test_macro_list_invalid_macro(base_app, capsys): # Look up invalid macro - out = run_cmd(base_app, 'macro list invalid') + run_cmd(base_app, 'macro list invalid') out, err = capsys.readouterr() assert "Macro 'invalid' not found" in err @@ -2032,6 +2042,17 @@ def test_multiple_macros(base_app): expected = normalize(BASE_HELP_VERBOSE) assert out == expected +def test_nonexistent_macro(base_app, capsys): + from cmd2.parsing import StatementParser + exception = None + + try: + base_app._run_macro(StatementParser().parse('fake')) + except KeyError as e: + exception = e + + assert exception is not None + def test_ppaged(base_app): msg = 'testing...' |