cmd2 2.4.2__tar.gz → 2.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cmd2-2.5.0/.readthedocs.yaml +34 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/CHANGELOG.md +45 -17
- {cmd2-2.4.2 → cmd2-2.5.0}/LICENSE +1 -1
- {cmd2-2.4.2/cmd2.egg-info → cmd2-2.5.0}/PKG-INFO +20 -19
- cmd2-2.5.0/Pipfile +33 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/README.md +13 -12
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/__init__.py +2 -6
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/ansi.py +16 -13
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/argparse_completer.py +1 -10
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/argparse_custom.py +14 -55
- cmd2-2.5.0/cmd2/clipboard.py +25 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/cmd2.py +535 -236
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/command_definition.py +10 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/decorators.py +90 -64
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/exceptions.py +0 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/history.py +48 -19
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/parsing.py +36 -30
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/plugin.py +8 -6
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/py_bridge.py +14 -3
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/rl_utils.py +57 -23
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/table_creator.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/transcript.py +3 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/utils.py +58 -16
- {cmd2-2.4.2 → cmd2-2.5.0/cmd2.egg-info}/PKG-INFO +20 -19
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2.egg-info/SOURCES.txt +3 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2.egg-info/requires.txt +17 -15
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/cmd.rst +13 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/utils.rst +4 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/conf.py +19 -19
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/doc_conventions.rst +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/argument_processing.rst +0 -8
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/builtin_commands.rst +15 -14
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/clipboard.rst +8 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/commands.rst +1 -3
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/help.rst +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/hooks.rst +3 -3
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/initialization.rst +11 -7
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/multiline_commands.rst +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/prompt.rst +7 -3
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/scripting.rst +33 -33
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/settings.rst +15 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/transcripts.rst +4 -4
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/migrating/why.rst +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/overview/installation.rst +2 -2
- cmd2-2.5.0/docs/requirements.txt +8 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/testing.rst +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/alias_startup.py +3 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/arg_decorators.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/argparse_completion.py +1 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/async_printing.py +8 -5
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/basic.py +7 -6
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/basic_completion.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/colors.py +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/custom_parser.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/decorator_example.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/dynamic_commands.py +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/environment.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/event_loops.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/example.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/exit_code.py +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/hello_cmd2.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/help_categories.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/initialization.py +12 -11
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/migrating.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands/commandset_basic.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands/commandset_custominit.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands_main.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_subcommands.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/paged_output.py +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/persistent_history.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/pirate.py +1 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/python_scripting.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/read_input.py +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/remove_settable.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/conditional.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/save_help_text.py +0 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/script.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/table_creation.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/unicode_commands.py +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/noxfile.py +2 -9
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/build-pyenvs.sh +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/cmd2_ext_test/__init__.py +1 -7
- {cmd2-2.4.2/plugins/template → cmd2-2.5.0/plugins/ext_test}/noxfile.py +1 -1
- cmd2-2.5.0/plugins/ext_test/pyproject.toml +194 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/setup.py +3 -3
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/tasks.py +18 -10
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/tasks.py +23 -6
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/README.md +9 -20
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/build-pyenvs.sh +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/cmd2_myplugin/__init__.py +2 -6
- {cmd2-2.4.2/plugins/ext_test → cmd2-2.5.0/plugins/template}/noxfile.py +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/setup.py +3 -3
- cmd2-2.5.0/pyproject.toml +235 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/readme_files/shoutout.txt +39 -40
- cmd2-2.5.0/setup.cfg +4 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/setup.py +22 -16
- {cmd2-2.4.2 → cmd2-2.5.0}/tasks.py +21 -9
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/conftest.py +30 -14
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/raises_exception.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/recursive.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/script.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_ansi.py +1 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_argparse.py +42 -28
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_argparse_completer.py +3 -6
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_argparse_custom.py +1 -5
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_cmd2.py +219 -69
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_completion.py +5 -4
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_history.py +63 -4
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_parsing.py +25 -5
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_plugin.py +2 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_run_pyscript.py +22 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_table_creator.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_transcript.py +2 -2
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_utils.py +64 -23
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/test_utils_defining_class.py +3 -1
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/from_cmdloop.txt +1 -1
- cmd2-2.5.0/tests/transcripts/regex_set.txt +28 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests_isolated/test_commandset/conftest.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests_isolated/test_commandset/test_categories.py +1 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests_isolated/test_commandset/test_commandset.py +37 -3
- cmd2-2.4.2/Pipfile +0 -36
- cmd2-2.4.2/cmd2/clipboard.py +0 -44
- cmd2-2.4.2/pyproject.toml +0 -26
- cmd2-2.4.2/setup.cfg +0 -62
- cmd2-2.4.2/tests/transcripts/regex_set.txt +0 -27
- {cmd2-2.4.2 → cmd2-2.5.0}/MANIFEST.in +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/constants.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2/py.typed +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2.egg-info/dependency_links.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2.egg-info/top_level.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/cmd2.png +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/Makefile +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/ansi.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/argparse_completer.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/argparse_custom.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/command_definition.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/constants.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/decorators.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/exceptions.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/history.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/parsing.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/plugin.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/plugin_external_test.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/py_bridge.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/api/table_creator.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/examples/alternate_event_loops.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/examples/first_app.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/examples/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/completion.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/disable_commands.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/embedded_python_shells.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/generating_output.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/history.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/misc.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/modular_commands.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/os.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/packaging.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/plugins.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/redirection.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/shortcuts_aliases_macros.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/startup_commands.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/features/table_creation.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/make.bat +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/migrating/incompatibilities.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/migrating/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/migrating/minimum.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/migrating/next_steps.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/migrating/summary.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/overview/alternatives.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/overview/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/overview/integrating.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/overview/resources.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/overview/summary.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/plugins/external_test.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/docs/plugins/index.rst +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/.cmd2rc +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/arg_print.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/cmd_as_argument.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/default_categories.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/first_app.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/hooks.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands/__init__.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands/commandset_complex.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands_basic.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/modular_commands_dynamic.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/override_parser.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/remove_builtin_commands.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/arg_printer.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/nested.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/quit.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/scripts/script.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/subcommands.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/transcripts/exampleSession.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/transcripts/pirate.transcript +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/transcripts/quit.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/examples/transcripts/transcript_regex.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/README.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/CHANGELOG.md +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/README.md +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/cmd2_ext_test/cmd2_ext_test.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/cmd2_ext_test/py.typed +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/cmd2_ext_test/pylintrc +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/examples/example.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/tests/__init__.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/tests/pylintrc +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/ext_test/tests/test_ext_test.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/CHANGELOG.md +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/LICENSE +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/cmd2_myplugin/myplugin.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/cmd2_myplugin/pylintrc +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/examples/example.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/tasks.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/tests/__init__.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/tests/pylintrc +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/plugins/template/tests/test_myplugin.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/readme_files/shout_out.csv +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/.cmd2rc +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/__init__.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/echo.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/environment.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/help.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/py_locals.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/pyscript_dir.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/self_in_py.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/stdout_capture.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/pyscript/stop.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/relative_multiple.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/script.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/binary.bin +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/empty.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/help.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/nested.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/one_down.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/postcmds.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/precmds.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/scripts/utf8.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/bol_eol.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/characterclass.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/dotstar.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/extension_notation.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/failure.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/multiline_no_regex.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/multiline_regex.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/no_output.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/no_output_last.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/singleslash.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/slashes_escaped.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/slashslash.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/spaces.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests/transcripts/word_boundaries.txt +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests_isolated/__init__.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests_isolated/test_commandset/__init__.py +0 -0
- {cmd2-2.4.2 → cmd2-2.5.0}/tests_isolated/test_commandset/test_argparse_subcommands.py +0 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# Read the Docs configuration file for Sphinx projects
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
3
|
+
|
4
|
+
# Required
|
5
|
+
version: 2
|
6
|
+
|
7
|
+
# Set the OS, Python version and other tools you might need
|
8
|
+
build:
|
9
|
+
os: ubuntu-22.04
|
10
|
+
tools:
|
11
|
+
python: "3.12"
|
12
|
+
|
13
|
+
# Build documentation in the "docs/" directory with Sphinx
|
14
|
+
sphinx:
|
15
|
+
configuration: docs/conf.py
|
16
|
+
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
|
17
|
+
# builder: "dirhtml"
|
18
|
+
# Fail on all warnings to avoid broken references
|
19
|
+
# fail_on_warning: true
|
20
|
+
|
21
|
+
# Optionally build your docs in additional formats such as PDF and ePub
|
22
|
+
# formats:
|
23
|
+
# - pdf
|
24
|
+
# - epub
|
25
|
+
formats: all
|
26
|
+
|
27
|
+
# Optional but recommended, declare the Python requirements required to build your documentation
|
28
|
+
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
|
29
|
+
python:
|
30
|
+
install:
|
31
|
+
- method: pip
|
32
|
+
path: .
|
33
|
+
extra_requirements:
|
34
|
+
- docs
|
@@ -1,3 +1,31 @@
|
|
1
|
+
## 2.5.0 (October 23, 2024)
|
2
|
+
* Breaking Change
|
3
|
+
* `cmd2` 2.5 supports Python 3.8+ (removed support for Python 3.6 and 3.7)
|
4
|
+
* Bug Fixes
|
5
|
+
* Fixed issue where persistent history file was not saved upon SIGHUP and SIGTERM signals.
|
6
|
+
* Multiline commands are no longer fragmented in up-arrow history.
|
7
|
+
* Fixed bug where `async_alert()` overwrites readline's incremental and non-incremental search prompts.
|
8
|
+
* This fix introduces behavior where an updated prompt won't display after an aborted search
|
9
|
+
until a user presses Enter. See [async_printing.py](https://github.com/python-cmd2/cmd2/blob/master/examples/async_printing.py)
|
10
|
+
example for how to handle this case using `Cmd.need_prompt_refresh()` and `Cmd.async_refresh_prompt()`.
|
11
|
+
* Enhancements
|
12
|
+
* Removed dependency on `attrs` and replaced with [dataclasses](https://docs.python.org/3/library/dataclasses.html)
|
13
|
+
* add `allow_clipboard` initialization parameter and attribute to disable ability to
|
14
|
+
add output to the operating system clipboard
|
15
|
+
* Updated unit tests to be Python 3.13 compliant.
|
16
|
+
* Fall back to bz2 compression of history file when lzma is not installed.
|
17
|
+
* Added settable called `scripts_add_to_history` which determines whether scripts and pyscripts
|
18
|
+
add commands to history.
|
19
|
+
* Deletions (potentially breaking changes)
|
20
|
+
* Removed `apply_style` from `Cmd.pwarning()`.
|
21
|
+
|
22
|
+
## 2.4.3 (January 27, 2023)
|
23
|
+
* Bug Fixes
|
24
|
+
* Fixed ValueError caused when passing `Cmd.columnize()` strings wider than `display_width`.
|
25
|
+
* Enhancements
|
26
|
+
* Renamed `utils.str_to_bool()` -> `utils.to_bool()`.
|
27
|
+
* Enhanced `utils.to_bool()` so that it accepts and converts `bool`, `int`, and `float` in addition to `str`.
|
28
|
+
|
1
29
|
## 2.4.2 (July 13, 2022)
|
2
30
|
* Enhancements
|
3
31
|
* Updated argparse decorator to remove annotations when the docstring is used for a command's help text.
|
@@ -77,7 +105,7 @@
|
|
77
105
|
* Added `ap_completer_type` keyword arg to `Cmd2ArgumentParser.__init__()` which saves a call
|
78
106
|
to `set_ap_completer_type()`. This keyword will also work with `add_parser()` when creating subcommands
|
79
107
|
if the base command's parser is a `Cmd2ArgumentParser`.
|
80
|
-
* New function `register_argparse_argument_parameter()` allows developers to specify custom
|
108
|
+
* New function `register_argparse_argument_parameter()` allows developers to specify custom
|
81
109
|
parameters to be passed to the argparse parser's `add_argument()` method. These parameters will
|
82
110
|
become accessible in the resulting argparse Action object when modifying `ArgparseCompleter` behavior.
|
83
111
|
* Using `SimpleTable` in the output for the following commands to improve appearance.
|
@@ -250,12 +278,12 @@
|
|
250
278
|
|
251
279
|
## 1.3.7 (August 27, 2020)
|
252
280
|
* Bug Fixes
|
253
|
-
* Fixes an issue introduced in 1.3.0 with processing command strings containing terminator/separator
|
281
|
+
* Fixes an issue introduced in 1.3.0 with processing command strings containing terminator/separator
|
254
282
|
character(s) that are manually passed to a command that uses argparse.
|
255
283
|
|
256
284
|
## 1.3.6 (August 27, 2020)
|
257
285
|
* Breaking changes
|
258
|
-
* The functions cmd2 adds to Namespaces (`get_statement()` and `get_handler()`) are now
|
286
|
+
* The functions cmd2 adds to Namespaces (`get_statement()` and `get_handler()`) are now
|
259
287
|
`Cmd2AttributeWrapper` objects named `cmd2_statement` and `cmd2_handler`. This makes it
|
260
288
|
easy to filter out which attributes in an `argparse.Namespace` were added by `cmd2`.
|
261
289
|
* Deprecations
|
@@ -281,7 +309,7 @@
|
|
281
309
|
* Breaking changes
|
282
310
|
* CommandSet command functions (do_, complete_, help_) will no longer have the cmd2 app
|
283
311
|
passed in as the first parameter after `self` since this is already a class member.
|
284
|
-
* Renamed `install_command_set()` and `uninstall_command_set()` to `register_command_set()` and
|
312
|
+
* Renamed `install_command_set()` and `uninstall_command_set()` to `register_command_set()` and
|
285
313
|
`unregister_command_set()` for better name consistency.
|
286
314
|
* Bug Fixes
|
287
315
|
* Fixed help formatting bug in `Cmd2ArgumentParser` when `metavar` is a tuple
|
@@ -291,8 +319,8 @@
|
|
291
319
|
* Removed explicit type hints that fail due to a bug in 3.5.2 favoring comment-based hints instead
|
292
320
|
* When passing a ns_provider to an argparse command, will now attempt to resolve the correct
|
293
321
|
CommandSet instance for self. If not, it'll fall back and pass in the cmd2 app
|
294
|
-
* Other
|
295
|
-
* Added missing doc-string for new cmd2.Cmd __init__ parameters
|
322
|
+
* Other
|
323
|
+
* Added missing doc-string for new cmd2.Cmd __init__ parameters
|
296
324
|
introduced by CommandSet enhancement
|
297
325
|
|
298
326
|
## 1.3.2 (August 10, 2020)
|
@@ -307,8 +335,8 @@
|
|
307
335
|
## 1.3.1 (August 6, 2020)
|
308
336
|
* Bug Fixes
|
309
337
|
* Fixed issue determining whether an argparse completer function required a reference to a containing
|
310
|
-
CommandSet. Also resolves issues determining the correct CommandSet instance when calling the argparse
|
311
|
-
argument completer function. Manifested as a TypeError when using `cmd2.Cmd.path_complete` as a completer
|
338
|
+
CommandSet. Also resolves issues determining the correct CommandSet instance when calling the argparse
|
339
|
+
argument completer function. Manifested as a TypeError when using `cmd2.Cmd.path_complete` as a completer
|
312
340
|
for an argparse-based command defined in a CommandSet
|
313
341
|
|
314
342
|
## 1.3.0 (August 4, 2020)
|
@@ -317,7 +345,7 @@
|
|
317
345
|
with your cmd2 application.
|
318
346
|
* Other
|
319
347
|
* Marked with_argparser_and_unknown_args pending deprecation and consolidated implementation into
|
320
|
-
with_argparser
|
348
|
+
with_argparser
|
321
349
|
|
322
350
|
## 1.2.1 (July 14, 2020)
|
323
351
|
* Bug Fixes
|
@@ -325,7 +353,7 @@
|
|
325
353
|
|
326
354
|
## 1.2.0 (July 13, 2020)
|
327
355
|
* Bug Fixes
|
328
|
-
* Fixed `typing` module compatibility issue with Python 3.5 prior to 3.5.4
|
356
|
+
* Fixed `typing` module compatibility issue with Python 3.5 prior to 3.5.4
|
329
357
|
* Enhancements
|
330
358
|
* Switched to getting version using `importlib.metadata` instead of using `pkg_resources`
|
331
359
|
* Improves `cmd2` application launch time on systems that have a lot of Python packages on `sys.path`
|
@@ -334,7 +362,7 @@
|
|
334
362
|
## 1.1.0 (June 6, 2020)
|
335
363
|
* Bug Fixes
|
336
364
|
* Fixed issue where subcommand usage text could contain a subcommand alias instead of the actual name
|
337
|
-
* Fixed bug in `ArgparseCompleter` where `fill_width` could become negative if `token_width` was large
|
365
|
+
* Fixed bug in `ArgparseCompleter` where `fill_width` could become negative if `token_width` was large
|
338
366
|
relative to the terminal width.
|
339
367
|
* Enhancements
|
340
368
|
* Made `ipy` consistent with `py` in the following ways
|
@@ -358,7 +386,7 @@
|
|
358
386
|
after parsing fails, just return instead of raising an exception.
|
359
387
|
* Added explicit handling of `SystemExit`. If a command raises this exception, the command loop will be
|
360
388
|
gracefully stopped.
|
361
|
-
|
389
|
+
|
362
390
|
## 1.0.2 (April 06, 2020)
|
363
391
|
* Bug Fixes
|
364
392
|
* Ctrl-C now stops a running text script instead of just the current `run_script` command
|
@@ -381,9 +409,9 @@
|
|
381
409
|
* Bug Fixes
|
382
410
|
* Corrected issue where the actual new value was not always being printed in do_set. This occurred in cases where
|
383
411
|
the typed value differed from what the setter had converted it to.
|
384
|
-
* Fixed bug where ANSI style sequences were not correctly handled in `utils.truncate_line()`.
|
412
|
+
* Fixed bug where ANSI style sequences were not correctly handled in `utils.truncate_line()`.
|
385
413
|
* Fixed bug where pyscripts could edit `cmd2.Cmd.py_locals` dictionary.
|
386
|
-
* Fixed bug where cmd2 set `sys.path[0]` for a pyscript to cmd2's working directory instead of the
|
414
|
+
* Fixed bug where cmd2 set `sys.path[0]` for a pyscript to cmd2's working directory instead of the
|
387
415
|
script file's directory.
|
388
416
|
* Fixed bug where `sys.path` was not being restored after a pyscript ran.
|
389
417
|
* Enhancements
|
@@ -697,7 +725,7 @@
|
|
697
725
|
* Enhancements
|
698
726
|
* Added ability to include command name placeholders in the message printed when trying to run a disabled command.
|
699
727
|
* See docstring for ``disable_command()`` or ``disable_category()`` for more details.
|
700
|
-
* Added instance attributes to customize error messages without having to override methods.
|
728
|
+
* Added instance attributes to customize error messages without having to override methods. These messages can
|
701
729
|
also be colored.
|
702
730
|
* `help_error` - the error that prints when no help information can be found
|
703
731
|
* `default_error` - the error that prints when a non-existent command is run
|
@@ -834,7 +862,7 @@
|
|
834
862
|
* Aliases are now sorted alphabetically
|
835
863
|
* The **set** command now tab completes settable parameter names
|
836
864
|
* Added ``async_alert``, ``async_update_prompt``, and ``set_window_title`` functions
|
837
|
-
* These allow you to provide feedback to the user in an
|
865
|
+
* These allow you to provide feedback to the user in an asynchronous fashion, meaning alerts can
|
838
866
|
display when the user is still entering text at the prompt. See [async_printing.py](https://github.com/python-cmd2/cmd2/blob/master/examples/async_printing.py)
|
839
867
|
for an example.
|
840
868
|
* Cross-platform colored output support
|
@@ -934,7 +962,7 @@
|
|
934
962
|
* New pyscript approach that provides a pythonic interface to commands in the cmd2 application.
|
935
963
|
* Switch command parsing from pyparsing to custom code which utilizes shlex.
|
936
964
|
* The object passed to do_* methods has changed. It no longer is the pyparsing object, it's a new Statement object, which is a subclass of ``str``. The statement object has many attributes which give you access to various components of the parsed input. If you were using anything but the string in your do_* methods, this change will require you to update your code.
|
937
|
-
* ``
|
965
|
+
* ``commentGrammars`` is no longer supported or available. Comments are C-style or python style.
|
938
966
|
* Input redirection no longer supported. Use the load command instead.
|
939
967
|
* ``multilineCommand`` attribute is ``now multiline_command``
|
940
968
|
* ``identchars`` is now ignored. The standardlibrary cmd uses those characters to split the first "word" of the input, but cmd2 hasn't used those for a while, and the new parsing logic parses on whitespace, which has the added benefit of full unicode support, unlike cmd or prior versions of cmd2.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2008-
|
3
|
+
Copyright (c) 2008-2024 Catherine Devlin and others
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: cmd2
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.5.0
|
4
4
|
Summary: cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python
|
5
5
|
Home-page: https://github.com/python-cmd2/cmd2
|
6
6
|
Author: Catherine Devlin
|
@@ -16,17 +16,19 @@ Classifier: Intended Audience :: System Administrators
|
|
16
16
|
Classifier: License :: OSI Approved :: MIT License
|
17
17
|
Classifier: Programming Language :: Python
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
19
|
-
Classifier: Programming Language :: Python :: 3.6
|
20
|
-
Classifier: Programming Language :: Python :: 3.7
|
21
19
|
Classifier: Programming Language :: Python :: 3.8
|
22
20
|
Classifier: Programming Language :: Python :: 3.9
|
23
21
|
Classifier: Programming Language :: Python :: 3.10
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
24
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
25
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
26
|
-
Requires-Python: >=3.
|
27
|
+
Requires-Python: >=3.8
|
27
28
|
Description-Content-Type: text/markdown
|
28
|
-
Provides-Extra: test
|
29
29
|
Provides-Extra: dev
|
30
|
+
Provides-Extra: docs
|
31
|
+
Provides-Extra: test
|
30
32
|
Provides-Extra: validate
|
31
33
|
License-File: LICENSE
|
32
34
|
|
@@ -34,18 +36,19 @@ License-File: LICENSE
|
|
34
36
|
|
35
37
|
[](https://pypi.python.org/pypi/cmd2/)
|
36
38
|
[](https://github.com/python-cmd2/cmd2/actions?query=workflow%3ACI)
|
37
|
-
[](https://python-cmd2.visualstudio.com/cmd2/_build/latest?definitionId=1&branch=master)
|
38
39
|
[](https://codecov.io/gh/python-cmd2/cmd2)
|
39
40
|
[](http://cmd2.readthedocs.io/en/latest/?badge=latest)
|
40
41
|
<a href="https://discord.gg/RpVG6tk"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg" alt="Chat"></a>
|
41
42
|
|
42
43
|
|
43
44
|
<p align="center">
|
44
|
-
<a href="#
|
45
|
+
<a href="#the-developers-toolbox">Developer's Toolbox</a> •
|
46
|
+
<a href="#philosophy">Philosophy</a> •
|
45
47
|
<a href="#installation">Installation</a> •
|
48
|
+
<a href="#documentation">Documentation</a> •
|
46
49
|
<a href="#tutorials">Tutorials</a> •
|
50
|
+
<a href="#hello-world">Hello World</a> •
|
47
51
|
<a href="#projects-using-cmd2">Projects using cmd2</a> •
|
48
|
-
<a href="#version-two-notes">Version 2.0 Notes</a>
|
49
52
|
</p>
|
50
53
|
|
51
54
|
[](https://youtu.be/DDU_JH6cFsA)
|
@@ -63,14 +66,14 @@ The developers toolbox
|
|
63
66
|

|
64
67
|
|
65
68
|
|
66
|
-
When creating solutions developers have no shortage of tools to create rich and smart user interfaces.
|
67
|
-
System administrators have long been duct taping together brittle workflows based on a menagerie of simple command line tools created by strangers on github and the guy down the hall.
|
68
|
-
Unfortunately, when CLIs become significantly complex the ease of command discoverability tends to fade quickly.
|
69
|
-
On the other hand, Web and traditional desktop GUIs are first in class when it comes to easily discovering functionality.
|
69
|
+
When creating solutions developers have no shortage of tools to create rich and smart user interfaces.
|
70
|
+
System administrators have long been duct taping together brittle workflows based on a menagerie of simple command line tools created by strangers on github and the guy down the hall.
|
71
|
+
Unfortunately, when CLIs become significantly complex the ease of command discoverability tends to fade quickly.
|
72
|
+
On the other hand, Web and traditional desktop GUIs are first in class when it comes to easily discovering functionality.
|
70
73
|
The price we pay for beautifully colored displays is complexity required to aggregate disperate applications into larger systems.
|
71
|
-
`cmd2` fills the niche between high [ease of command discovery](https://clig.dev/#ease-of-discovery) applications and smart workflow automation systems.
|
74
|
+
`cmd2` fills the niche between high [ease of command discovery](https://clig.dev/#ease-of-discovery) applications and smart workflow automation systems.
|
72
75
|
|
73
|
-
The `cmd2` framework provides a great mixture of both worlds. Application designers can easily create complex applications and rely on the cmd2 library to offer effortless user facing help and extensive tab completion.
|
76
|
+
The `cmd2` framework provides a great mixture of both worlds. Application designers can easily create complex applications and rely on the cmd2 library to offer effortless user facing help and extensive tab completion.
|
74
77
|
When users become comfortable with functionality, cmd2 turns into a feature rich library enabling a smooth transition to full automation. If designed with enough forethought, a well implemented cmd2 application can serve as a boutique workflow tool. `cmd2` pulls off this flexibility based on two pillars of philosophy:
|
75
78
|
|
76
79
|
* Tab Completion
|
@@ -109,7 +112,7 @@ On all operating systems, the latest stable version of `cmd2` can be installed u
|
|
109
112
|
pip install -U cmd2
|
110
113
|
```
|
111
114
|
|
112
|
-
cmd2 works with Python 3.
|
115
|
+
cmd2 works with Python 3.8+ on Windows, macOS, and Linux. It is pure Python code with few 3rd-party dependencies.
|
113
116
|
|
114
117
|
For information on other installation options, see
|
115
118
|
[Installation Instructions](https://cmd2.readthedocs.io/en/latest/overview/installation.html) in the cmd2
|
@@ -128,7 +131,7 @@ The best way to learn the cmd2 api is to delve into the example applications loc
|
|
128
131
|
Tutorials
|
129
132
|
---------
|
130
133
|
|
131
|
-
* PyOhio 2019 presentation:
|
134
|
+
* PyOhio 2019 presentation:
|
132
135
|
* [video](https://www.youtube.com/watch?v=pebeWrTqIIw)
|
133
136
|
* [slides](https://github.com/python-cmd2/talks/blob/master/PyOhio_2019/cmd2-PyOhio_2019.pdf)
|
134
137
|
* [example code](https://github.com/python-cmd2/talks/tree/master/PyOhio_2019/examples)
|
@@ -192,6 +195,4 @@ Projects using cmd2
|
|
192
195
|
Possibly defunct but still good examples
|
193
196
|
|
194
197
|
* [JSShell](https://github.com/Den1al/JSShell)
|
195
|
-
* [FLASHMINGO](https://github.com/fireeye/flashmingo)
|
196
|
-
|
197
|
-
|
198
|
+
* [FLASHMINGO](https://github.com/fireeye/flashmingo)
|
cmd2-2.5.0/Pipfile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
[[source]]
|
2
|
+
name = "pypi"
|
3
|
+
url = "https://pypi.org/simple"
|
4
|
+
verify_ssl = true
|
5
|
+
|
6
|
+
[packages]
|
7
|
+
pyperclip = "*"
|
8
|
+
setuptools = "*"
|
9
|
+
wcwidth = "*"
|
10
|
+
|
11
|
+
[dev-packages]
|
12
|
+
build = "*"
|
13
|
+
cmd2 = { editable = true, path = "." }
|
14
|
+
cmd2_ext_test = { editable = true, path = "plugins/ext_test" }
|
15
|
+
codecov = "*"
|
16
|
+
doc8 = "*"
|
17
|
+
gnureadline = { version = "*", sys_platform = "== 'darwin'" }
|
18
|
+
invoke = "*"
|
19
|
+
ipython = "*"
|
20
|
+
mypy = "*"
|
21
|
+
pyreadline3 = { version = ">=3.4", sys_platform = "== 'win32'" }
|
22
|
+
pytest = "*"
|
23
|
+
pytest-cov = "*"
|
24
|
+
pytest-mock = "*"
|
25
|
+
ruff = "*"
|
26
|
+
setuptools-scm = "*"
|
27
|
+
sphinx = "*"
|
28
|
+
sphinx-autobuild = "*"
|
29
|
+
sphinx-rtd-theme = "*"
|
30
|
+
twine = ">=1.11"
|
31
|
+
|
32
|
+
[pipenv]
|
33
|
+
allow_prereleases = true
|
@@ -2,18 +2,19 @@
|
|
2
2
|
|
3
3
|
[](https://pypi.python.org/pypi/cmd2/)
|
4
4
|
[](https://github.com/python-cmd2/cmd2/actions?query=workflow%3ACI)
|
5
|
-
[](https://python-cmd2.visualstudio.com/cmd2/_build/latest?definitionId=1&branch=master)
|
6
5
|
[](https://codecov.io/gh/python-cmd2/cmd2)
|
7
6
|
[](http://cmd2.readthedocs.io/en/latest/?badge=latest)
|
8
7
|
<a href="https://discord.gg/RpVG6tk"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg" alt="Chat"></a>
|
9
8
|
|
10
9
|
|
11
10
|
<p align="center">
|
12
|
-
<a href="#
|
11
|
+
<a href="#the-developers-toolbox">Developer's Toolbox</a> •
|
12
|
+
<a href="#philosophy">Philosophy</a> •
|
13
13
|
<a href="#installation">Installation</a> •
|
14
|
+
<a href="#documentation">Documentation</a> •
|
14
15
|
<a href="#tutorials">Tutorials</a> •
|
16
|
+
<a href="#hello-world">Hello World</a> •
|
15
17
|
<a href="#projects-using-cmd2">Projects using cmd2</a> •
|
16
|
-
<a href="#version-two-notes">Version 2.0 Notes</a>
|
17
18
|
</p>
|
18
19
|
|
19
20
|
[](https://youtu.be/DDU_JH6cFsA)
|
@@ -31,14 +32,14 @@ The developers toolbox
|
|
31
32
|

|
32
33
|
|
33
34
|
|
34
|
-
When creating solutions developers have no shortage of tools to create rich and smart user interfaces.
|
35
|
-
System administrators have long been duct taping together brittle workflows based on a menagerie of simple command line tools created by strangers on github and the guy down the hall.
|
36
|
-
Unfortunately, when CLIs become significantly complex the ease of command discoverability tends to fade quickly.
|
37
|
-
On the other hand, Web and traditional desktop GUIs are first in class when it comes to easily discovering functionality.
|
35
|
+
When creating solutions developers have no shortage of tools to create rich and smart user interfaces.
|
36
|
+
System administrators have long been duct taping together brittle workflows based on a menagerie of simple command line tools created by strangers on github and the guy down the hall.
|
37
|
+
Unfortunately, when CLIs become significantly complex the ease of command discoverability tends to fade quickly.
|
38
|
+
On the other hand, Web and traditional desktop GUIs are first in class when it comes to easily discovering functionality.
|
38
39
|
The price we pay for beautifully colored displays is complexity required to aggregate disperate applications into larger systems.
|
39
|
-
`cmd2` fills the niche between high [ease of command discovery](https://clig.dev/#ease-of-discovery) applications and smart workflow automation systems.
|
40
|
+
`cmd2` fills the niche between high [ease of command discovery](https://clig.dev/#ease-of-discovery) applications and smart workflow automation systems.
|
40
41
|
|
41
|
-
The `cmd2` framework provides a great mixture of both worlds. Application designers can easily create complex applications and rely on the cmd2 library to offer effortless user facing help and extensive tab completion.
|
42
|
+
The `cmd2` framework provides a great mixture of both worlds. Application designers can easily create complex applications and rely on the cmd2 library to offer effortless user facing help and extensive tab completion.
|
42
43
|
When users become comfortable with functionality, cmd2 turns into a feature rich library enabling a smooth transition to full automation. If designed with enough forethought, a well implemented cmd2 application can serve as a boutique workflow tool. `cmd2` pulls off this flexibility based on two pillars of philosophy:
|
43
44
|
|
44
45
|
* Tab Completion
|
@@ -77,7 +78,7 @@ On all operating systems, the latest stable version of `cmd2` can be installed u
|
|
77
78
|
pip install -U cmd2
|
78
79
|
```
|
79
80
|
|
80
|
-
cmd2 works with Python 3.
|
81
|
+
cmd2 works with Python 3.8+ on Windows, macOS, and Linux. It is pure Python code with few 3rd-party dependencies.
|
81
82
|
|
82
83
|
For information on other installation options, see
|
83
84
|
[Installation Instructions](https://cmd2.readthedocs.io/en/latest/overview/installation.html) in the cmd2
|
@@ -96,7 +97,7 @@ The best way to learn the cmd2 api is to delve into the example applications loc
|
|
96
97
|
Tutorials
|
97
98
|
---------
|
98
99
|
|
99
|
-
* PyOhio 2019 presentation:
|
100
|
+
* PyOhio 2019 presentation:
|
100
101
|
* [video](https://www.youtube.com/watch?v=pebeWrTqIIw)
|
101
102
|
* [slides](https://github.com/python-cmd2/talks/blob/master/PyOhio_2019/cmd2-PyOhio_2019.pdf)
|
102
103
|
* [example code](https://github.com/python-cmd2/talks/tree/master/PyOhio_2019/examples)
|
@@ -160,4 +161,4 @@ Projects using cmd2
|
|
160
161
|
Possibly defunct but still good examples
|
161
162
|
|
162
163
|
* [JSShell](https://github.com/Den1al/JSShell)
|
163
|
-
* [FLASHMINGO](https://github.com/fireeye/flashmingo)
|
164
|
+
* [FLASHMINGO](https://github.com/fireeye/flashmingo)
|
@@ -5,12 +5,8 @@
|
|
5
5
|
|
6
6
|
import sys
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
import importlib.metadata as importlib_metadata
|
11
|
-
else:
|
12
|
-
# For everyone else
|
13
|
-
import importlib_metadata
|
8
|
+
import importlib.metadata as importlib_metadata
|
9
|
+
|
14
10
|
try:
|
15
11
|
__version__ = importlib_metadata.version(__name__)
|
16
12
|
except importlib_metadata.PackageNotFoundError: # pragma: no cover
|
@@ -2,7 +2,8 @@
|
|
2
2
|
"""
|
3
3
|
Support for ANSI escape sequences which are used for things like applying style to text,
|
4
4
|
setting the window title, and asynchronous alerts.
|
5
|
-
|
5
|
+
"""
|
6
|
+
|
6
7
|
import functools
|
7
8
|
import re
|
8
9
|
from enum import (
|
@@ -62,25 +63,25 @@ The default is ``AllowStyle.TERMINAL``.
|
|
62
63
|
"""
|
63
64
|
|
64
65
|
# Regular expression to match ANSI style sequence
|
65
|
-
ANSI_STYLE_RE = re.compile(
|
66
|
+
ANSI_STYLE_RE = re.compile(rf'{ESC}\[[^m]*m')
|
66
67
|
|
67
68
|
# Matches standard foreground colors: CSI(30-37|90-97|39)m
|
68
|
-
STD_FG_RE = re.compile(
|
69
|
+
STD_FG_RE = re.compile(rf'{ESC}\[(?:[39][0-7]|39)m')
|
69
70
|
|
70
71
|
# Matches standard background colors: CSI(40-47|100-107|49)m
|
71
|
-
STD_BG_RE = re.compile(
|
72
|
+
STD_BG_RE = re.compile(rf'{ESC}\[(?:(?:4|10)[0-7]|49)m')
|
72
73
|
|
73
74
|
# Matches eight-bit foreground colors: CSI38;5;(0-255)m
|
74
|
-
EIGHT_BIT_FG_RE = re.compile(
|
75
|
+
EIGHT_BIT_FG_RE = re.compile(rf'{ESC}\[38;5;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])m')
|
75
76
|
|
76
77
|
# Matches eight-bit background colors: CSI48;5;(0-255)m
|
77
|
-
EIGHT_BIT_BG_RE = re.compile(
|
78
|
+
EIGHT_BIT_BG_RE = re.compile(rf'{ESC}\[48;5;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])m')
|
78
79
|
|
79
80
|
# Matches RGB foreground colors: CSI38;2;(0-255);(0-255);(0-255)m
|
80
|
-
RGB_FG_RE = re.compile(
|
81
|
+
RGB_FG_RE = re.compile(rf'{ESC}\[38;2(?:;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])){{3}}m')
|
81
82
|
|
82
83
|
# Matches RGB background colors: CSI48;2;(0-255);(0-255);(0-255)m
|
83
|
-
RGB_BG_RE = re.compile(
|
84
|
+
RGB_BG_RE = re.compile(rf'{ESC}\[48;2(?:;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])){{3}}m')
|
84
85
|
|
85
86
|
|
86
87
|
def strip_style(text: str) -> str:
|
@@ -224,7 +225,6 @@ class BgColor(AnsiSequence):
|
|
224
225
|
####################################################################################
|
225
226
|
# Implementations intended for direct use
|
226
227
|
####################################################################################
|
227
|
-
# noinspection PyPep8Naming
|
228
228
|
class Cursor:
|
229
229
|
"""Create ANSI sequences to alter the cursor position"""
|
230
230
|
|
@@ -1042,6 +1042,9 @@ def style(
|
|
1042
1042
|
# Default styles for printing strings of various types.
|
1043
1043
|
# These can be altered to suit an application's needs and only need to be a
|
1044
1044
|
# function with the following structure: func(str) -> str
|
1045
|
+
style_output = functools.partial(style)
|
1046
|
+
"""Partial function supplying arguments to :meth:`cmd2.ansi.style()` which colors text for normal output"""
|
1047
|
+
|
1045
1048
|
style_success = functools.partial(style, fg=Fg.GREEN)
|
1046
1049
|
"""Partial function supplying arguments to :meth:`cmd2.ansi.style()` which colors text to signify success"""
|
1047
1050
|
|
@@ -1056,7 +1059,7 @@ def async_alert_str(*, terminal_columns: int, prompt: str, line: str, cursor_off
|
|
1056
1059
|
"""Calculate the desired string, including ANSI escape codes, for displaying an asynchronous alert message.
|
1057
1060
|
|
1058
1061
|
:param terminal_columns: terminal width (number of columns)
|
1059
|
-
:param prompt:
|
1062
|
+
:param prompt: current onscreen prompt
|
1060
1063
|
:param line: current contents of the Readline line buffer
|
1061
1064
|
:param cursor_offset: the offset of the current cursor position within line
|
1062
1065
|
:param alert_msg: the message to display to the user
|
@@ -1069,9 +1072,9 @@ def async_alert_str(*, terminal_columns: int, prompt: str, line: str, cursor_off
|
|
1069
1072
|
# Calculate how many terminal lines are taken up by all prompt lines except for the last one.
|
1070
1073
|
# That will be included in the input lines calculations since that is where the cursor is.
|
1071
1074
|
num_prompt_terminal_lines = 0
|
1072
|
-
for
|
1073
|
-
|
1074
|
-
num_prompt_terminal_lines += int(
|
1075
|
+
for prompt_line in prompt_lines[:-1]:
|
1076
|
+
prompt_line_width = style_aware_wcswidth(prompt_line)
|
1077
|
+
num_prompt_terminal_lines += int(prompt_line_width / terminal_columns) + 1
|
1075
1078
|
|
1076
1079
|
# Now calculate how many terminal lines are take up by the input
|
1077
1080
|
last_prompt_line = prompt_lines[-1]
|
@@ -61,7 +61,6 @@ DEFAULT_DESCRIPTIVE_HEADER = 'Description'
|
|
61
61
|
ARG_TOKENS = 'arg_tokens'
|
62
62
|
|
63
63
|
|
64
|
-
# noinspection PyProtectedMember
|
65
64
|
def _build_hint(parser: argparse.ArgumentParser, arg_action: argparse.Action) -> str:
|
66
65
|
"""Build tab completion hint for a given argument"""
|
67
66
|
# Check if hinting is disabled for this argument
|
@@ -82,7 +81,6 @@ def _single_prefix_char(token: str, parser: argparse.ArgumentParser) -> bool:
|
|
82
81
|
return len(token) == 1 and token[0] in parser.prefix_chars
|
83
82
|
|
84
83
|
|
85
|
-
# noinspection PyProtectedMember
|
86
84
|
def _looks_like_flag(token: str, parser: argparse.ArgumentParser) -> bool:
|
87
85
|
"""
|
88
86
|
Determine if a token looks like a flag. Unless an argument has nargs set to argparse.REMAINDER,
|
@@ -94,7 +92,7 @@ def _looks_like_flag(token: str, parser: argparse.ArgumentParser) -> bool:
|
|
94
92
|
return False
|
95
93
|
|
96
94
|
# Flags have to start with a prefix character
|
97
|
-
if
|
95
|
+
if token[0] not in parser.prefix_chars:
|
98
96
|
return False
|
99
97
|
|
100
98
|
# If it looks like a negative number, it is not a flag unless there are negative-number-like flags
|
@@ -144,7 +142,6 @@ class _ArgumentState:
|
|
144
142
|
self.max = self.action.nargs
|
145
143
|
|
146
144
|
|
147
|
-
# noinspection PyProtectedMember
|
148
145
|
class _UnfinishedFlagError(CompletionError):
|
149
146
|
def __init__(self, flag_arg_state: _ArgumentState) -> None:
|
150
147
|
"""
|
@@ -171,7 +168,6 @@ class _NoResultsError(CompletionError):
|
|
171
168
|
super().__init__(_build_hint(parser, arg_action), apply_style=False)
|
172
169
|
|
173
170
|
|
174
|
-
# noinspection PyProtectedMember
|
175
171
|
class ArgparseCompleter:
|
176
172
|
"""Automatic command line tab completion based on argparse parameters"""
|
177
173
|
|
@@ -273,10 +269,8 @@ class ArgparseCompleter:
|
|
273
269
|
# Check if this action is in a mutually exclusive group
|
274
270
|
for group in self._parser._mutually_exclusive_groups:
|
275
271
|
if arg_action in group._group_actions:
|
276
|
-
|
277
272
|
# Check if the group this action belongs to has already been completed
|
278
273
|
if group in completed_mutex_groups:
|
279
|
-
|
280
274
|
# If this is the action that completed the group, then there is no error
|
281
275
|
# since it's allowed to appear on the command line more than once.
|
282
276
|
completer_action = completed_mutex_groups[group]
|
@@ -307,7 +301,6 @@ class ArgparseCompleter:
|
|
307
301
|
# Parse all but the last token
|
308
302
|
#############################################################################################
|
309
303
|
for token_index, token in enumerate(tokens[:-1]):
|
310
|
-
|
311
304
|
# If we're in a positional REMAINDER arg, force all future tokens to go to that
|
312
305
|
if pos_arg_state is not None and pos_arg_state.is_remainder:
|
313
306
|
consume_argument(pos_arg_state)
|
@@ -339,7 +332,6 @@ class ArgparseCompleter:
|
|
339
332
|
|
340
333
|
# Check the format of the current token to see if it can be an argument's value
|
341
334
|
if _looks_like_flag(token, self._parser) and not skip_remaining_flags:
|
342
|
-
|
343
335
|
# Check if there is an unfinished flag
|
344
336
|
if (
|
345
337
|
flag_arg_state is not None
|
@@ -484,7 +476,6 @@ class ArgparseCompleter:
|
|
484
476
|
|
485
477
|
# Otherwise check if we have a positional to complete
|
486
478
|
elif pos_arg_state is not None or remaining_positionals:
|
487
|
-
|
488
479
|
# If we aren't current tracking a positional, then get the next positional arg to handle this token
|
489
480
|
if pos_arg_state is None:
|
490
481
|
action = remaining_positionals.popleft()
|