Visitar URL original
Comparing main...persistent-bottom-bar · python-cmd2/cmd2 · GitHub
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: python-cmd2/cmd2
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: python-cmd2/cmd2
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: persistent-bottom-bar
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 10 commits
  • 8 files changed
  • 2 contributors

Commits on Sep 5, 2026

  1. Implemented: enable_bottom_toolbar=True now keeps the toolbar visible…

    … and refreshing during command execution. Prompts, pagers, and shell commands temporarily suspend it while using the terminal.
    
    Try the work command examples/getting_started.py for a demonstration.
    
    The feature uses two prompt-toolkit displays at different times: the existing PromptSession while waiting for input, and a dedicated CommandToolbar while commands execute.
    
    - Command execution stays on the main thread. The command loop starts the toolbar’s UI in a background thread, using the same content callback, styling, and refresh interval.
    - Output appears above the toolbar. Stable stream wrappers route Python and piped subprocess output through prompt-toolkit’s output proxy. Their identities remain consistent across cmd2 redirection and toolbar suspension.
    - Input remains coordinated. The toolbar handles terminal position reports, saves typed-ahead keys for the next prompt, and forwards Ctrl-C to the main thread.
    - Other terminal interfaces get exclusive access. Nested prompts, pagers, and shell commands temporarily suspend the toolbar. Custom commands can do the same with suspend_bottom_toolbar().
    - Cleanup restores normal terminal operation. When execution ends, buffered output is flushed, workers are stopped, and the original streams are restored.
    
    Most supporting code lives in cmd2/command_toolbar.py, with lifecycle integration in cmd2/cmd2.py. Because get_bottom_toolbar() runs in the UI thread during commands, shared mutable state should be protected with a lock.
    tleonhardt committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    76dcc78 View commit details
    Browse the repository at this point in the history
  2. Various bug fixes

    1. Pipes to interactive targets (cmd2.py:3366, command_toolbar.py:43) — the pipe process now inherits the real terminal via the new pipe_target() helper, and the toolbar suspends for the life of the pipe (held in RedirectionSavedState.toolbar_suspension, released in _restore_output). Streams with no file descriptor still fall back to PIPE. Verified under a real pty: alias | python3 -c "...isatty()" printed PIPE_ISATTY True; before the fix that command produced no output at all.
    
    2. Ctrl-C not reaching subprocesses (command_toolbar.py:161) — POSIX now uses os.killpg(os.getpgrp(), SIGINT), matching what the terminal driver does. Verified under a pty with a child that reports its own SIGINT: post-fix CHILD_GOT_SIGINT appears and the child exits immediately; pre-fix it never fired and the child ran to completion. Windows keeps interrupt_main() — broadcasting a console control event there would hit unrelated processes on the same console. Ctrl-\ stays inert, which matches the main prompt's existing behavior; documented rather than changed.
    
    3. Failing stop() disabling the toolbar (cmd2.py:2098) — _command_toolbar = None moved into its own finally.
    
    4. Writes racing _pause() (command_toolbar.py) — an RLock shared by the toolbar and its ToolbarStreams serializes writes against the proxy swap. The lock is deliberately released before _thread.join(), since the toolbar thread can itself be blocked writing through a stream.
    
    5. Post-startup failures swallowed — new _app_exited() detaches the streams when the display stops on its own, so output goes to the terminal instead of a dead proxy, and reports the error. Worth noting: the review's stated trigger doesn't hold — a get_bottom_toolbar() that raises on refresh is caught by asyncio's default handler and the thread survives. The fix targets the case where the thread genuinely dies.
    
    6. Final flush cancelled before writing — does not reproduce. Application.run_async already awaits wait_for_cpr_responses() and any in-flight run_in_terminal futures before its loop closes (application.py:770-779). I built the exact scenario — an output with responds_to_cpr=True and a CPR future confirmed pending at pause time — and the trailing text arrived with and without the proposed fix. I reverted my drain implementation, which was adding a run_in_terminal round-trip and up to a second of CPR waiting at every command boundary for nothing. I kept the test as a regression guard and a two-line guard against Application.exit() raising in a loop callback if the app has already stopped.
    
    7. Docs/example mismatch — do_work now uses Annotated[int, Argument(nargs="?")], so work and work 5 both work. Verified in the real app.
    tleonhardt committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    1c491b1 View commit details
    Browse the repository at this point in the history
  3. Fix Windows CI failures in command toolbar tests

    Three tests called _read_raw_input() after the toolbar context had exited,
    so no prompt-toolkit app session was active. patch_stdout() then asked the
    default app session for its output, which lazily builds a real terminal
    Output: harmless Vt100_Output on POSIX, but Win32Output on Windows, which
    raises NoConsoleScreenBufferError without a console screen buffer of the
    kind GitHub Actions does not provide.
    
    Bind the fixture's app session to the test pipe and recording output so
    every prompt-toolkit call in these tests resolves to the test terminal
    rather than the ambient one.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01C7nkx8kKC2mpaMGfLwXe6J
    tleonhardt and claude committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    1702654 View commit details
    Browse the repository at this point in the history
  4. Cover the toolbar's EOF shutdown path

    Closing the terminal's input ends the display's Application.run() with
    EOFError, which _resume() swallows because it is an ordinary shutdown
    rather than a failure the running command should hear about. Nothing
    exercised that handler, leaving it as the one uncovered line in the new
    module.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01C7nkx8kKC2mpaMGfLwXe6J
    tleonhardt and claude committed Sep 5, 2026
    Configuration menu
    Copy the full SHA
    6cb419d View commit details
    Browse the repository at this point in the history

Commits on Sep 6, 2026

  1. Configuration menu
    Copy the full SHA
    41eb9c8 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    1afe262 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    10f16ea View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    063deed View commit details
    Browse the repository at this point in the history

Commits on Sep 8, 2026

  1. Merge branch 'main' into persistent-bottom-bar

    # Conflicts:
    #	CHANGELOG.md
    tleonhardt committed Sep 8, 2026
    Configuration menu
    Copy the full SHA
    dad3786 View commit details
    Browse the repository at this point in the history

Commits on Sep 12, 2026

  1. Configuration menu
    Copy the full SHA
    cd7f05f View commit details
    Browse the repository at this point in the history
Loading