Skip to content

Extract the wrapping text-entry popup and put quick-create and link-PR on it - #169

Merged
MJohnson459 merged 1 commit into
mainfrom
wrapping-text-entry-popup
Aug 14, 2026
Merged

MJohnson459 merged 1 commit into
mainfrom
wrapping-text-entry-popup

Conversation

@MJohnson459

Copy link
Copy Markdown
Contributor

Three modal arms in crates/voro/src/ui.rs drew a single typed buffer into a
bordered popup, but only Mode::Prompt sized the box from the wrapped line
count. Mode::LinkPr and Mode::QuickCreate asked popup_area for a fixed
three rows, two of them borders, so everything past the first wrapped row — the
▏ cursor included — was clipped: the operator typing a long intent into n, or
pasting a long PR URL, was typing blind.

What changed

The prompt's body is now draw_text_entry_popup(frame, title, buffer), sitting
beside popup_area as part of the same popup toolbox. It splits the buffer on
'\n', appends the cursor to the last line, builds a wrapping Paragraph,
measures it with line_count at the popup's inner width, sizes the box
rendered_rows.clamp(3, 20) and past the clamp scrolls to the tail. Width 72,
the clamp and the tail scroll are the prompt's numbers unchanged, now named as
WIDTH/MIN_ROWS/MAX_ROWS constants. Both explanatory comments — the
'\n'-vs-wrapped-count note and the RejectWork multi-line one — moved across
with the code they describe.

All three arms call it and are one line each plus their title, which each
passes whole because the suffixes genuinely differ ("⏎ to submit" for the
prompt and link-PR, "⏎ to propose" for quick create). Mode::QuickCreate still
resolves the project name from app.projects exactly as before,
unwrap_or("the project") and all. No copy of the measure/clamp/scroll block
survives. The helper takes no hits and pushes nothing, so the arms still
register no click target.

Key handling is untouched — App::key_quick_create and key_link_pr are not
in the diff. Mode::AddProject and the viewer form are deliberately left
alone: two-field forms with focus styling are a different shape, and bending
the helper to fit them was out of scope. Nothing in DESIGN.md needed changing;
this was a rendering defect, not a change to documented modal semantics.

Verification

Two new tests mirror the existing prompt pair over Mode::QuickCreate:
quick_create_popup_grows_with_wrapped_text and
quick_create_popup_scrolls_to_the_tail_when_it_overflows. render_prompt was
generalised into render_modal(store, mode) with thin render_prompt /
render_quick_create wrappers, the quick-create one seeding
store.create_project("voro", "/tmp/voro") before App::new so the title
resolves. I confirmed both new tests are load-bearing by temporarily restoring
the old three-row arm — both fail against it, then pass again with the helper.
prompt_popup_grows_with_wrapped_text and
prompt_popup_scrolls_to_the_tail_when_it_overflows pass unchanged.

cargo test --workspace (470 + 389 + 1, 0 failed), cargo clippy --workspace --all-targets -- -D warnings and cargo fmt --all are all clean.

Manually driven through the verify skill against a scratch db in tmux at
110x30. Pressing n with one project goes straight to quick create; typing
~130 columns wrapped to two rows with TAILMARK▏ visible, and typing on past
the clamp pinned the tail and cursor on the last row while the head scrolled
out of the 20-row box. g on a non-review task opened the link-PR prompt,
where a 116-character URL wrapped across two rows with the cursor visible —
both previously clipped. The refine popup still renders exactly as before.

Three modal arms drew a single typed buffer into a bordered popup, but only
Mode::Prompt sized the box from the wrapped line count. LinkPr and QuickCreate
asked for a fixed three rows, two of them borders, so a long intent or a pasted
PR URL vanished past the first wrapped row — the cursor with it, leaving the
operator typing blind.

Extract the prompt's measure/clamp/scroll block into draw_text_entry_popup
beside popup_area and put all three arms on it, each passing its whole title
because the submit suffixes differ. The width, the 3..=20 row clamp and the
tail scroll are the prompt's, unchanged.

Verified with two new tests mirroring the prompt pair over Mode::QuickCreate —
they fail against the old three-row arm — and by driving the TUI: a long intent
in the n modal wraps and grows to the clamp, then scrolls to keep the tail and
the cursor on screen, and a long URL in the link-PR prompt wraps the same way.
The refine popup is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ABF2CHfKV8sp2gSzJLsQ4T
@MJohnson459
MJohnson459 merged commit 9ce9d36 into main Aug 14, 2026
7 checks passed
@MJohnson459
MJohnson459 deleted the wrapping-text-entry-popup branch August 14, 2026 17:09
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.

1 participant