Update cmd2.Cmd.select to use prompt-toolkit choice#1600
Update cmd2.Cmd.select to use prompt-toolkit choice#1600tleonhardt wants to merge 5 commits intomainfrom
Conversation
Key Changes:
- prompt_toolkit.shortcuts.choice integration: The select method now utilizes the modern, interactive choice shortcut when both stdin and stdout are TTYs. This
provides a more user-friendly selection menu (usually supports arrow keys and searching).
- Backward Compatibility: Maintained the original numbered-list implementation as a fallback for non-TTY environments. This ensures that existing scripts,
pipes, and tests (which mock read_input) continue to function correctly.
- Robust Argument Handling: Standardized the conversion of various input formats (strings, lists of strings, lists of tuples) to the (value, label) format
required by choice.
- Error Handling: Wrapped the choice call in a loop and a try-except block to correctly handle KeyboardInterrupt (Ctrl-C) by printing ^C and re-raising, and to
handle cancellations by reprompting, maintaining consistency with original select behavior.
|
🤖 Hi @tleonhardt, I've received your request, and I'm working on it now! You can track my progress in the logs for more details. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1600 +/- ##
=======================================
Coverage 99.51% 99.51%
=======================================
Files 21 21
Lines 4714 4725 +11
=======================================
+ Hits 4691 4702 +11
Misses 23 23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
|
🤖 I'm sorry @tleonhardt, but I was unable to process your request. Please see the logs for more details. |
| super().__init__() | ||
| self.remove_settable('debug') | ||
|
|
||
| def do_eat(self, arg): |
There was a problem hiding this comment.
Why put an example for select() in the example about removing Settables?
| except (IndexError, TypeError): | ||
| fulloptions.append((opt[0], str(opt[0]))) | ||
|
|
||
| if self.stdin.isatty() and self.stdout.isatty(): |
There was a problem hiding this comment.
I suggest changing this to if self._is_tty_session(self.main_session):
Otherwise the choice function won't run when in a pyscript or when redirecting the output of a command.
| monkeypatch.setattr("cmd2.cmd2.choice", choice_mock) | ||
|
|
||
| # Mock isatty to be True for both stdin and stdout | ||
| monkeypatch.setattr(outsim_app.stdin, "isatty", lambda: True) |
There was a problem hiding this comment.
If you make the logic change I suggested in select(), replace these isatty monkeypatches with something like this:
with create_pipe_input() as pipe_input:
base_app.main_session = PromptSession(
input=pipe_input,
output=DummyOutput(),
)
prompt = 'Sauce? '
options = ['sweet', 'salty']
...Do the same for the next test.
The choice function from
prompt-toolkitis now used forcmd2.Cmd.selectmethod when both stdin and stdout are TTYs.Key Changes:
prompt_toolkit.shortcuts.choiceintegration: Theselectmethod now utilizes the modern, interactive choice shortcut when both stdin and stdout are TTYs. This provides a more user-friendly selection menu (usually supports arrow keys and searching).