Skip to content

feat(gpui): a bindable clear-screen action for the terminal - #653

Open
zher52 wants to merge 17 commits into
Kuddev:mainfrom
zher52:feat/gpui-clear-terminal-action
Open

zher52 wants to merge 17 commits into
Kuddev:mainfrom
zher52:feat/gpui-clear-terminal-action

Conversation

@zher52

@zher52 zher52 commented Oct 15, 2026

Copy link
Copy Markdown

Result / 用户结果

Users can now bind a clear-screen shortcut themselves. The GPUI shell had no clear-screen action at all: the macOS config table's ⌘K → ClearHistory default executes only in the legacy shell, so after unbinding the Shell picker row ⌘K stayed inert and no settings row offered clear screen — the known limitation recorded in the 2026-09-21 macOS command-key aliases note ("⌘K after unbinding does not clear the screen").

Settings → Key Bindings gains a Terminal-group "Clear screen / 清屏" row. No default shortcut changes on any platform: ⌘K stays on the Shell picker, and the feature is opt-in through a user keybind= row (e.g. keybind=cmd+k:ClearHistory) that applies without restart.

Design / 设计边界

  • Responsibility and affected modules: gpui_shell/workspace/keyboard_bindings.rs maps config::Action::ClearHistory to a new ClearTerminal workspace action (alongside the SelectTab/QuitApp adapter actions); gpui_shell/terminal/view.rs implements the pane-level clear; display/keymap.rs owns the editable row; catalogs add common.clear_screen. The existing keymap authority (config table + MACOS_COMMAND_ALIASES unbind vocabulary) is reused unchanged.
  • After an instant app-side wipe of the viewport and scrollback (ClearMode::All + Saved), the action branches on the pane's foreground state:
    • Shell at a prompt (OSC 133 nebula_prompt_active): writes ^L to that pane's PTY so the shell repaints its prompt on the fresh screen with its line state in sync (same visible behavior as the legacy ⌘K pair).
    • Command running: no PTY write — a queued ^L would clear the screen a second time when the command exits, wiping the output produced in between. The view moves the terminal cursor home app-side; sequential output continues from the top.
    • Alternate screen (vim/less): no-op; ^L is a redraw there, not a clear.
  • Dependency, data-format, threading, or lifetime changes: none. ^L is a direct PTY write on the focused pane, not a user-input event, so broadcast fan-out is untouched.
  • Compatibility and migration/fallback: the legacy shell is unaffected; Windows/Linux gain an unbound row; without shell integration the prompt probe reads false and clears take the cursor-home branch (the next Enter restores the prompt). Decision record: architecture/notes/nebula_app/gpui_shell/2026-10-14-terminal-clear-action.md.

Evidence / 验证依据

  • cargo fmt --all -- --check; cargo check -p nebula --bin pebrel --features gpui-shell --tests --locked (0 errors); keyboard_bindings 25 passed (including the gpui-test-support dispatch module), display::keymap 46 passed, settings_pane 24 passed, i18n contract 24 passed, nebula-settings 99 passed, file_line_budget 2 passed; python3 scripts/check_architecture.py --base <merge-base 13659697> passes with budgets unchanged — the new action lives in keyboard_bindings.rs specifically because workspace.rs sits at its ratcheted 2773-line budget.
  • Regression tests: clear_history_maps_to_the_clear_terminal_action fails without the adapter arm (a user-bound clear must win over the static ⌘K picker binding while Ctrl+K stays on the picker); clear_screen_shortcut_dispatches_and_stays_out_of_the_terminal_stream fails without the dispatch path (the key must not enter the PTY input stream); clear_screen_is_editable_and_localized_through_the_typed_message fails without the catalog entries.
  • UI changes: exercised manually on macOS 26 x64 (debug build, isolated PEBREL_CONFIG_DIR): prompt clear repaints at the top-left, clear during a running command keeps output flowing from the top, vim is untouched, the Shell picker keeps Ctrl+K, and the binding survives restart. Platform/feature coverage limitation: Windows/Linux paths rely on the shared keymap tests and CI; no native manual run there.
  • Not a hot-path change (keystroke-triggered cold path).

Required Review / 必须确认

  • I followed CONTRIBUTING.md, docs/architecture.md, and docs/project-constraints.md.
  • I split responsibilities, not arbitrary line ranges; no duplicate behavior authority was added.
  • python3 scripts/check_architecture.py --base <PR-base-commit> passes; budgets were not inflated to fit the change.
  • Tests cover success and failure; platform/feature coverage limitations are stated.
  • New messages use typed i18n IDs and matching placeholders; untranslated content has an explicit fallback.

@zher52
zher52 requested a review from Kuddev as a code owner October 15, 2026 06:18
@zher52
zher52 force-pushed the feat/gpui-clear-terminal-action branch 3 times, most recently from 1b43c7e to 2bec420 Compare October 15, 2026 07:56
The GPUI shell had no clear-screen action at all: the macOS config
table's ⌘K ClearHistory default executes only in the legacy shell, so
after unbinding the Shell picker row ⌘K stayed inert and no settings
row offered clear screen — the known limitation recorded in the
2026-09-21 macOS command-key aliases note.

Map config::Action::ClearHistory to a new ClearTerminal workspace
action and expose it as a Terminal-group row on the settings keymap
page. No default shortcut changes on any platform: ⌘K stays on the
Shell picker, and the feature is opt-in through a user keybind= row
that applies without restart. After an instant app-side wipe of the
viewport and scrollback, the action branches on the pane's foreground
state: at a prompt it writes ^L to the pane's PTY so the shell
repaints its prompt on the fresh screen; while a command runs it
moves the terminal cursor home app-side so sequential output
continues from the top; on the alternate screen it does nothing. The
row label uses a typed i18n message (zh/en catalogs, English fallback
elsewhere).

Adds adapter, dispatch-probe and label regressions, and the decision
note architecture/notes/nebula_app/gpui_shell/2026-10-14-terminal-clear-action.md
(recording why pre-existing files need one re-record after upgrading,
and why an app-side cursor-home and an unconditional ^L were rejected).
…trol group

The platform-cfg ratchet counts cfg! macros outside platform/ and the
clear-screen adapter regression added one. Build the static default
keymap identically on every platform instead: the precedence being
tested is source-tier, not platform-specific, and the macOS-only
registration behavior stays guarded by its own runtime-platform test.
…policy

Upstream cf77ccd releases plain Control-character workspace defaults on
macOS, so the Shell picker's Ctrl+K default may legitimately be absent.
Derive the Ctrl+K expectation from the control group's own shape instead
of asserting it unconditionally; the user clear binding must neither
steal a present default nor resurrect a released key.
@zher52
zher52 force-pushed the feat/gpui-clear-terminal-action branch from 10520b6 to 94cdb39 Compare October 19, 2026 02:35
@Kuddev

Kuddev commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Added focused maintainer fixes at 92516fe and merged the current main baseline. The actual TerminalView tests now cover prompt-only Ctrl+L delivery, no PTY input while a command runs, cursor-home/history/selection clearing, and an unchanged alternate screen plus primary history. The macOS keymap regression preserves Command+K ownership for the Shell picker; the stale note has been corrected.

Windows validation: cargo test --locked -p nebula --bin pebrel --features gpui-test-support clear_screen -- --test-threads=1 passed all 4 matched tests. Architecture and whitespace checks passed. The previous macOS failure was in the unchanged ai_hook::unix::tests::local_hook_socket_routes_identity_and_releases_its_private_directory shutdown call (ENOTCONN); the new head is now running the full native matrix, so this is not yet a claim that all platform checks pass.

The action is user-triggered: it reuses the terminal's existing bounded grid/history clear operations and adds one prompt-state branch, with no polling or background work. Native shell redraw acceptance remains distinct from the standalone PTY regression fixtures.

Kuddev
Kuddev previously approved these changes Oct 19, 2026

@Kuddev Kuddev left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed db35ebd. All five actual Native tests jobs and both macOS release workspace checks passed on this head. The clear action now reaches the focused GPUI terminal; focused regression cases verify prompt-only Ctrl+L, running-command cursor reset without PTY input, cleared viewport/history/selection, and an unchanged alternate screen. The shortcut policy retains Command+K for the macOS Shell picker, with Clear screen unbound until explicitly assigned.

This is a user-triggered operation using the existing grid/history clear primitives, with no polling, extra subprocess, or per-frame work. Windows focused tests and architecture checks passed locally. The standalone PTY fixture proves dispatched bytes and terminal state; it is not a claim that every third-party shell redraw behavior was exercised.

@zher52

zher52 commented Oct 22, 2026

Copy link
Copy Markdown
Author

The Full native tests failure on the previous head was the Windows-only nebula_terminal::tty::windows::test::bash_input::git_bash_wrapped_input_can_be_fully_erased_in_byte_and_utf8_locales case. It is not touched by this PR — the branch changes nothing under nebula_terminal/, so the test and the code under test in this branch are byte-identical to upstream main, where the full Windows native suite is green on the latest runs (e.g. the merge of #694). The test drives a real Git Bash subprocess through a PTY with 5 ms polling and fixed 2 s / 10 s capture windows, so it is timing-sensitive on shared runners; the failure output shows its own Ctrl-L diagnostic capture reporting a mid-redraw state.

Re-running via an empty push; if it fails again consistently, it reproduces independently of this branch and likely needs a look upstream.

@zher52

zher52 commented Oct 22, 2026

Copy link
Copy Markdown
Author

The re-run failed on the same case: nebula_terminal::tty::windows::test::bash_input::git_bash_wrapped_input_can_be_fully_erased_in_byte_and_utf8_locales, panicking at bash_input.rs:142, both times on the windows-11-arm native runner (run 1, run 2); the windows-2022 native job passed in the same runs, and the remaining red jobs are the aggregate policy reports.

This branch changes nothing under nebula_terminal/, so the failing test and the code under test are identical to upstream main, where the Windows native suites are green on the latest runs (including windows-11-arm, e.g. the #694 merge). The test drives a real Git Bash subprocess through a PTY with fixed 2 s capture and 10 s wait windows; on windows-11-arm the x64 Git Bash binary runs under emulation, which makes those deadlines sensitive to runner load.

Since PR authors cannot re-run upstream jobs, could a maintainer re-run the failed job once? If it keeps failing there while main stays green, the flake reproduces independently of this PR and likely needs a look at the test's timing budget on emulated runners — happy to help dig.

@zher52

zher52 commented Oct 27, 2026

Copy link
Copy Markdown
Author

Friendly ping for a re-review. Your Oct 19 approval was dismissed as stale by the follow-up pushes (the repo requires approval of the latest reviewable push), and PR authors cannot re-request reviewers, so this comment is the nudge.

The branch is now conflict-free against main (merged through #694-era changes, v2.2.2 and v2.3.0 included) and every check is green on the latest head (4022ff2). Relative to the reviewed db35ebd, the behavioral diff is small: main's keymap refactor replaced action_label with the action_message typed-message table and the Clear screen row joined that table; the terminal clear semantics and the regressions are unchanged. Details in the merge commit and the decision note.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants