Skip to content

Commit 6c6d844

Browse files
authored
Add a new complete_in_thread parameter to cmd2.Cmd.__init__ that defaults to True (#1682)
If this parameter is True, then completion is performed in a background thread separate from the main REPL thread. If False, completion is performed in the main thread and can block the main thread if slow.
1 parent 32a7a63 commit 6c6d844

4 files changed

Lines changed: 30 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 4.1.0 (TBD)
2+
3+
- Enhancements
4+
- New `cmd2.Cmd` parameters
5+
- **complete_in_thread**: (boolean) if `True`, then completion will run in a separate
6+
thread. If `False` then completion runs in the main thread and causes it to block if slow.
7+
Defaults to `True`.
8+
19
## 4.0.0 (June 5, 2026)
210

311
### Summary

cmd2/cmd2.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ def __init__(
368368
auto_load_commands: bool = False,
369369
auto_suggest: bool = True,
370370
bottom_toolbar: bool = False,
371+
complete_in_thread: bool = True,
371372
command_sets: Iterable[CommandSet[Any]] | None = None,
372373
include_ipy: bool = False,
373374
include_py: bool = False,
@@ -404,6 +405,7 @@ def __init__(
404405
based on history. User can press right-arrow key to accept the
405406
provided suggestion.
406407
:param bottom_toolbar: if ``True``, then a bottom toolbar will be displayed.
408+
:param complete_in_thread: if ``True``, then completion will run in a separate thread.
407409
:param command_sets: Provide CommandSet instances to load during cmd2 initialization.
408410
This allows CommandSets with custom constructor parameters to be
409411
loaded. This also allows the a set of CommandSets to be provided
@@ -528,6 +530,7 @@ def __init__(
528530

529531
# Create the main PromptSession
530532
self.bottom_toolbar = bottom_toolbar
533+
self.complete_in_thread = complete_in_thread
531534
self.main_session = self._create_main_session(auto_suggest, completekey)
532535

533536
# The session currently holding focus (either the main REPL or a command's
@@ -752,7 +755,7 @@ def _(event: Any) -> None: # pragma: no cover
752755
"bottom_toolbar": self.get_bottom_toolbar if self.bottom_toolbar else None,
753756
"color_depth": ColorDepth.TRUE_COLOR,
754757
"complete_style": CompleteStyle.MULTI_COLUMN,
755-
"complete_in_thread": True,
758+
"complete_in_thread": self.complete_in_thread,
756759
"complete_while_typing": False,
757760
"completer": Cmd2Completer(self),
758761
"history": Cmd2History(item.raw for item in self.history),

docs/features/initialization.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Here are instance attributes of `cmd2.Cmd` which developers might wish to overri
3535

3636
- **bottom_toolbar**: if `True`, then a bottom toolbar will be displayed (Default: `False`)
3737
- **broken_pipe_warning**: if non-empty, this string will be displayed if a broken pipe error occurs
38+
- **complete_in_thread**: if `True`, then completion will run in a separate thread (Default: `True`)
3839
- **continuation_prompt**: used for multiline commands on 2nd+ line of input
3940
- **debug**: if `True`, show full stack trace on error (Default: `False`)
4041
- **default_error**: the error that prints when a non-existent command is run

tests/test_cmd2.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ def test_version(base_app) -> None:
6464
assert cmd2.__version__
6565

6666

67+
def test_complete_in_thread() -> None:
68+
# Test default
69+
app_default = cmd2.Cmd()
70+
assert app_default.complete_in_thread is True
71+
assert app_default.main_session.complete_in_thread is True
72+
73+
# Test True
74+
app_true = cmd2.Cmd(complete_in_thread=True)
75+
assert app_true.complete_in_thread is True
76+
assert app_true.main_session.complete_in_thread is True
77+
78+
# Test False
79+
app_false = cmd2.Cmd(complete_in_thread=False)
80+
assert app_false.complete_in_thread is False
81+
assert app_false.main_session.complete_in_thread is False
82+
83+
6784
def test_not_in_main_thread(base_app, capsys) -> None:
6885
import threading
6986

0 commit comments

Comments
 (0)