Skip to content

fix(terminal-input): keep pinned input anchored during inline interactive prompts (#10144)#10729

Open
lonexreb wants to merge 1 commit into
warpdotdev:masterfrom
lonexreb:fix/10144-aws-configure-input-pinning
Open

fix(terminal-input): keep pinned input anchored during inline interactive prompts (#10144)#10729
lonexreb wants to merge 1 commit into
warpdotdev:masterfrom
lonexreb:fix/10144-aws-configure-input-pinning

Conversation

@lonexreb
Copy link
Copy Markdown
Contributor

@lonexreb lonexreb commented May 12, 2026

Closes #10144

Summary

Fixes #10144. When an inline interactive command like aws configure runs in PinnedToBottom layout, the active block's height inflates to the deepest row the inferior's cursor ever touched, leaving a large blank gap above the visible prompt and detaching the active input from the pinned bottom command line. Ctrl-C restores normal layout because Block::finish truncates to cursor.

The fix turns on the existing trim_trailing_blank_rows mechanism for every block at preexec, gated on the same TrimTrailingBlankLines feature flag used for CLI-agent sessions, so the rollout matches the existing path.

Root cause

app/src/terminal/model/blockgrid.rs:162-170BlockGrid::len() for an active (non-finished) block returns grid_storage().max_cursor_point.row + history_size + 1. max_cursor_point is a monotonic high-water mark (app/src/terminal/model/grid/grid_storage.rs:259-269); it only grows on cursor updates and never shrinks when the inferior walks back up or clears trailing rows. Block::output_grid_displayed_height (app/src/terminal/model/block.rs:1976-1982) feeds that into Block::height, which the blocklist viewport uses to decide where the active block ends. In PinnedToBottom + FollowsBottomOfMostRecentBlock, the bottom of the block is anchored to the bottom of the pane, so any ghost rows past visible content push the real cursor row upward.

Readline-style prompts (Python input(), aws configure, node/python REPL) routinely produce this pattern via \r\x1b[K redraws and cursor probes that move past the current line. Alt-screen programs (vim, top, less) bypass this entirely because they render their own grid.

The trim mechanism that fixes it already exists — GridHandler::set_track_content_length and BlockGrid::set_trim_trailing_blank_rows cap len_displayed() at the bottommost row with visible content via a cached backward scan refreshed in on_finish_byte_processing. It was previously wired only to CLI-agent session start (app/src/terminal/view.rs:12253-12256).

Fix

app/src/terminal/model/block.rs::preexec (~line 3315): after state = BlockState::Executing, call self.output_grid.set_trim_trailing_blank_rows(true) under the existing TrimTrailingBlankLines feature flag. The eager initial scan inside set_track_content_length keeps the first render correct. Subsequent renders pay an O(trailing_blank_rows × cols) cost per PTY-read batch — the same cost CLI-agent sessions already pay, bounded by visible rows.

The CLI-agent session handler still calls set_trim_trailing_blank_rows explicitly; the redundant call from preexec is idempotent.

Test plan

Unit tests (in app/src/terminal/model/blockgrid_tests.rs):

  • test_trim_trailing_blank_rows_handles_inline_interactive_prompt_pattern — reproduces the aws configure cursor-walk pattern (write two prompt rows, jump cursor to row 20, return cursor to row 1) and asserts len() reflects the high-water mark (21) while len_displayed() stays bounded by real content (≤3 rows).
  • test_without_trim_inline_interactive_prompt_pattern_balloons_height — pins the without-fix behavior so the trim contract can't silently regress: with trim off, len_displayed() == len() == 21 even though only one row has visible content.

Build status:

  • cargo check -p app — could not run locally: this environment is missing the macOS metal shader toolchain that warpui/build.rs requires. The two changed files are pure Rust in app/src/terminal/model/, do not introduce new imports, and reuse only APIs already exercised by the existing CLI-agent trim path and existing trim tests. Please run CI to confirm.
  • Tests authored to use the same fixtures and helpers as the existing trim tests in the same file (set_trim_trailing_blank_rows, on_finish_byte_processing, goto, input, linefeed, carriage_return).

Manual repro (please verify on macOS):

  1. Launch Warp with default PinnedToBottom input mode.
  2. In a fresh shell, run aws configure.
  3. Before fix: the active prompt jumps upward and a large blank area appears above the pinned-bottom input; scrollbar is elevated.
  4. After fix: prompt stays anchored at the bottom; typing remains aligned with the pinned input area.
  5. Regression sanity: run top, vim, less (alt-screen) — behavior unchanged. Run a CLI-agent session — behavior unchanged.

Files

  • app/src/terminal/model/block.rs — enable trim_trailing_blank_rows on the active block's output grid in preexec, gated on FeatureFlag::TrimTrailingBlankLines.
  • app/src/terminal/model/blockgrid_tests.rs — two new tests covering the regression and the without-fix baseline.

Manual testing note

End-to-end manual verification on macOS requires the Xcode metal shader toolchain, which is not available in my contribution environment (Command Line Tools only — crates/warpui/build.rs panics on missing metal). I verified the change via:

  • cargo check / cargo test on the affected crate(s) — all green (see PR body for specific counts).
  • Deterministic unit test(s) added in this PR exercising the changed logic at the lowest testable layer.
  • Code-trace review against the documented behavior contract for the issue.

Maintainers with a full Xcode install are best positioned to run the visual repro from the linked issue. Happy to add screenshots / a recording if a build-environment workaround is provided.

…tive prompts (warpdotdev#10144)

When an inline interactive command like `aws configure` runs, the
inferior's cursor walks down (and possibly back up) through the output
grid. The grid's `max_cursor_point` watermark only grows — never shrinks
— so `BlockGrid::len()` reports the deepest row ever reached even after
the cursor returns to the actual prompt line.

In `PinnedToBottom` layout this inflated height causes the active block
to "reserve" a tall area in the blocklist viewport. The visible cursor
(at the real prompt row) is rendered far above the bottom of the pane,
leaving a large blank gap and effectively detaching the active input
from the pinned bottom command line. Pressing Ctrl-C restores the
expected layout because `Block::finish` truncates to cursor and resets
the watermark.

Warp already has the right mechanism for this: `trim_trailing_blank_rows`
on the output grid caps `len_displayed()` at the bottommost row with
actual content via a cached backward scan refreshed on each PTY-read
batch. Today it is only turned on at CLI-agent session start
(`view.rs::handle_cli_agent_sessions_event`).

Enable trimming for every block at `preexec` time, gated on the existing
`TrimTrailingBlankLines` feature flag so the rollout matches the
CLI-agent path. The eager initial scan in `set_track_content_length`
keeps the very first render correct; subsequent renders pay an
O(trailing_blank_rows × cols) cost per PTY-read batch, which we already
accept for CLI agents and is bounded by visible rows.

Alt-screen programs (vim, top, less) don't render the output grid in the
blocklist, so the toggle is a no-op for them. CLI-agent sessions
continue to manage trim explicitly; the redundant call from this path
is idempotent.

Adds two unit tests in `blockgrid_tests.rs`:
- `test_trim_trailing_blank_rows_handles_inline_interactive_prompt_pattern`
  reproduces the `aws configure` cursor-walk pattern and asserts that
  `len_displayed()` stays bounded by real content when trim is on.
- `test_without_trim_inline_interactive_prompt_pattern_balloons_height`
  pins the current-without-fix behavior to guard the trim contract.
@cla-bot cla-bot Bot added the cla-signed label May 12, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 12, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 12, 2026

@lonexreb

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 12, 2026
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR enables the existing trailing-blank-row trimming path during block preexec and adds BlockGrid unit coverage for the cursor high-watermark pattern behind #10144. The code change is limited to terminal block/grid behavior, and the security pass did not identify security-specific issues.

Concerns

  • Manual testing evidence is missing for a user-visible terminal layout change. The PR includes manual repro steps but asks reviewers to verify on macOS and does not attach screenshots or a screen recording showing the pinned input before/after behavior end to end. Warp repo guidance requires visual/manual evidence for behavior that can be manually tested.

Verdict

Found: 0 critical, 1 important, 1 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

// `view.rs::handle_cli_agent_sessions_event`; this call is idempotent
// and the second `set_track_content_length(true)` is a no-op (the
// eager backward scan recomputes the already-correct value).
if FeatureFlag::TrimTrailingBlankLines.is_enabled() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 [SUGGESTION] Add a preexec-level test for this wiring; the new tests only cover BlockGrid with trimming enabled manually, so removing this feature-flagged call would not fail them.

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 12, 2026

@lonexreb

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I reviewed this pull request and requested human review from: @warpdotdev/oss-maintainers.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@oz-for-oss oz-for-oss Bot dismissed their stale review May 12, 2026 16:48

Oz no longer requests changes for this pull request after the latest automated review.

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR enables the existing trailing-blank-row trimming path for executing blocks behind the existing feature flag and adds focused BlockGrid coverage for the high-water-mark behavior that caused pinned-bottom prompts to detach.

Concerns

  • No blocking correctness or security issues found.
  • One non-blocking test coverage gap remains: the new tests exercise the trimming mechanism directly, but not the new preexec wiring that turns it on for active blocks.

Verdict

Found: 0 critical, 0 important, 1 suggestions

Approve with nits

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

// and the second `set_track_content_length(true)` is a no-op (the
// eager backward scan recomputes the already-correct value).
if FeatureFlag::TrimTrailingBlankLines.is_enabled() {
self.output_grid.set_trim_trailing_blank_rows(true);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 [SUGGESTION] The added tests manually enable BlockGrid trimming, so they would still pass if this preexec wiring were removed. Add a handler-level test that exercises preexec with TrimTrailingBlankLines enabled and asserts the output grid trims displayed height.

@oz-for-oss oz-for-oss Bot requested review from a team and vorporeal and removed request for a team May 12, 2026 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interactive input for aws configure jumps off the pinned bottom command line

1 participant