Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0aa3a06
This is a very early non-working start of porting to use prompt-toolkit
tleonhardt Dec 26, 2025
e46744a
Fix complete_tester helper function in conftest.py so it passes all o…
tleonhardt Dec 29, 2025
9b12dd2
Remove remaining use of readline in cmd2.py and replace it with promp…
tleonhardt Dec 29, 2025
ef36ba2
Replace readline with prompt-toolkit in documentation and such
tleonhardt Dec 29, 2025
3d05273
Fix one history test
tleonhardt Dec 29, 2025
0a08c69
Remove reference to readline from test_history.py
tleonhardt Dec 29, 2025
e4c8abe
prompt-toolkit history now properly working with a persistent history…
tleonhardt Dec 29, 2025
5906d0e
Deleted rl_utils.py and removed all use of it
tleonhardt Dec 29, 2025
6c85dca
Add test_escaping_prompt test back but skip it for now with a TODO
tleonhardt Dec 29, 2025
d405a4f
Fix tests in tests_cmd2.py to monkeypatch cmd2.Cmd.read_input instead…
tleonhardt Dec 29, 2025
92faadc
Fix remaining tests in test_cmd2.py other than the one that is skipped
tleonhardt Dec 29, 2025
894368a
Renamed test_escaping_prompt to test_visible_prompt and fixed it to w…
tleonhardt Dec 29, 2025
100a98f
Fixed tests in test_run_pyscript for prompt-toolkit migration
tleonhardt Dec 29, 2025
798d400
Added test_pt_utils.py with unit tests to fully cover code in cmd2/pt…
tleonhardt Dec 29, 2025
ca4a6e7
Add 4.0.0 changes to CHANGELOG with details on readline migration to …
tleonhardt Dec 29, 2025
165e02e
Merge branch 'main' into prompt-toolkit
tleonhardt Dec 29, 2025
61cd1c0
Fixed bug where argument hints weren't displaying in color.
tleonhardt Dec 29, 2025
c263b38
Fix NoConsoleScreenBufferError on Windows CI by robustly initializing…
tleonhardt Dec 30, 2025
59c5ffa
Optimize GitHub Actions workflow by using PowerShell on Windows runne…
tleonhardt Dec 30, 2025
9aa7767
Revert "Optimize GitHub Actions workflow by using PowerShell on Windo…
tleonhardt Dec 30, 2025
0705adc
Try setting shell on Windows test runners
tleonhardt Dec 30, 2025
d0bf798
Try setting separate test steps for Windows vs Linux/Mac
tleonhardt Dec 30, 2025
f194db6
Revert "Fix NoConsoleScreenBufferError on Windows CI by robustly init…
tleonhardt Dec 30, 2025
123482e
Reapply "Fix NoConsoleScreenBufferError on Windows CI by robustly ini…
tleonhardt Dec 30, 2025
c0a283e
Revert to not explicitly setting shell on Windows in GitHub Actions
tleonhardt Dec 30, 2025
e16a59c
Try to fix one failing test on Windows
tleonhardt Dec 30, 2025
d68032e
Try to fix last test that is failing on Windows
tleonhardt Dec 30, 2025
2fe959e
Add some tests to test_cmd2.py to increase code coverage in cmd2.py
tleonhardt Dec 30, 2025
2052697
Added unit tests for the cmd2.Cmd._bottom_toolbar method
tleonhardt Dec 30, 2025
160b755
Add test to cover some uncovered exception handling code in cmd2.Cmd.…
tleonhardt Dec 30, 2025
2b2f51f
Add test to cover a few more lines of code
tleonhardt Dec 30, 2025
b3841d4
Add more test coverage and reduce repetition
tleonhardt Dec 30, 2025
b6e183e
Fix failing test
tleonhardt Dec 30, 2025
e4f58d8
Try to fix test failure
tleonhardt Dec 30, 2025
9753865
Add tests
tleonhardt Dec 30, 2025
b3bfe66
Add unit test for cmd2.Cmd._completion_supported
tleonhardt Dec 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ cmd2/exceptions.py @kmvanbrunt @anselor
cmd2/history.py @tleonhardt
cmd2/parsing.py @kmvanbrunt
cmd2/plugin.py @anselor
cmd2/pt_utils.py @kmvanbrunt @tleonhardt
cmd2/py_bridge.py @kmvanbrunt
cmd2/rich_utils.py @kmvanbrunt
cmd2/rl_utils.py @kmvanbrunt
cmd2/string_utils.py @kmvanbrunt
cmd2/styles.py @tleonhardt @kmvanbrunt
cmd2/terminal_utils.py @kmvanbrunt
Expand Down
16 changes: 7 additions & 9 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,13 @@ Nearly all project configuration, including for dependencies and quality tools i

See the `dependencies` list under the `[project]` heading in [pyproject.toml](../pyproject.toml).

| Prerequisite | Minimum Version | Purpose |
| ---------------------------------------------------------- | --------------- | ------------------------------------------------------ |
| [python](https://www.python.org/downloads/) | `3.10` | Python programming language |
| [pyperclip](https://github.com/asweigart/pyperclip) | `1.8` | Cross-platform clipboard functions |
| [rich](https://github.com/Textualize/rich) | `14.1.0` | Add rich text and beautiful formatting in the terminal |
| [rich-argparse](https://github.com/hamdanal/rich-argparse) | `1.7.1` | A rich-enabled help formatter for argparse |

> `macOS` and `Windows` each have an extra dependency to ensure they have a viable alternative to
> [readline](https://tiswww.case.edu/php/chet/readline/rltop.html) available.
| Prerequisite | Minimum Version | Purpose |
| ------------------------------------------------------------------------- | --------------- | ------------------------------------------------------ |
| [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) | `3.0.52` | Replacement for GNU `readline` that is cross-platform |
| [python](https://www.python.org/downloads/) | `3.10` | Python programming language |
| [pyperclip](https://github.com/asweigart/pyperclip) | `1.8` | Cross-platform clipboard functions |
| [rich](https://github.com/Textualize/rich) | `14.1.0` | Add rich text and beautiful formatting in the terminal |
| [rich-argparse](https://github.com/hamdanal/rich-argparse) | `1.7.1` | A rich-enabled help formatter for argparse |

> Python 3.10 depends on [backports.strenum](https://github.com/clbarnes/backports.strenum) to use
> the `enum.StrEnum` class introduced in Python 3.11.
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
## 4.0.0 (TBD 2026)

### Summary

`cmd2` now has a dependency on
[prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) which serves as a
pure-Python cross-platform replacement for
[GNU Readline](https://tiswww.case.edu/php/chet/readline/rltop.html). Previously, `cmd2` had used
different `readline` dependencies on each Operating System (OS) which was at times a very
frustrating developer and user experience due to small inconsistencies in these different readline
libraries. Now we have consistent cross-platform support for tab-completion, user terminal input,
and history. Additionally, this opens up some cool advanced features such as support for syntax
highlighting of user input while typing, auto-suggestions similar to those provided by the fish
shell, and the option for a persistent bottom bar that can display realtime status updates.

### Details

- Breaking Changes
- Removed all use of `readline` built-in module and underlying platform libraries
- Deleted `cmd2.rl_utils` module which dealt with importing the proper `readline` module for
each platform and provided utility functions related to `readline`
- Added a dependency on `prompt-toolkit` and a new `cmd2.pt_utils` module with supporting
utilities

## 3.1.0 (December 25, 2025)

- Potentially Breaking Changes
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ publish: validate-tag build ## Publish a release to PyPI, uses token from ~/.pyp
BUILD_DIRS = build dist *.egg-info
DOC_DIRS = build
MYPY_DIRS = .mypy_cache dmypy.json dmypy.sock
TEST_DIRS = .cache .coverage .pytest_cache htmlcov
TEST_DIRS = .cache .pytest_cache htmlcov
TEST_FILES = .coverage coverage.xml

.PHONY: clean-build
clean-build: ## Clean build artifacts
Expand Down Expand Up @@ -108,6 +109,7 @@ clean-ruff: ## Clean ruff artifacts
clean-test: ## Clean test artifacts
@echo "🚀 Removing test artifacts"
@uv run python -c "import shutil; import os; [shutil.rmtree(d, ignore_errors=True) for d in '$(TEST_DIRS)'.split() if os.path.isdir(d)]"
@uv run python -c "from pathlib import Path; [Path(f).unlink(missing_ok=True) for f in '$(TEST_FILES)'.split()]"

.PHONY: clean
clean: clean-build clean-docs clean-mypy clean-pycache clean-ruff clean-test ## Clean all artifacts
Expand Down
Loading
Loading