Skip to content

fix(url): extend URL detection across hard-wrap row boundaries#11613

Open
rndjams wants to merge 1 commit into
warpdotdev:masterfrom
rndjams:rndjams/fix-11609-url-hardwrap-join
Open

fix(url): extend URL detection across hard-wrap row boundaries#11613
rndjams wants to merge 1 commit into
warpdotdev:masterfrom
rndjams:rndjams/fix-11609-url-hardwrap-join

Conversation

@rndjams
Copy link
Copy Markdown

@rndjams rndjams commented May 23, 2026

Fixes #11609

Summary

AI TUI tools (Kiro CLI, Claude Code, GSD) write output with explicit \r\n, producing hard-wrapped rows where WRAPLINE is absent. When a URL overflows the terminal width, url_at_point returns only the first-row fragment — CMD+click opens a truncated, invalid URL.

Changes

1. url_at_point continuation probe (grid_handler.rs)

After the forward scan loop completes, probes across the hard-wrap boundary when:

  • URL ends within 4 cols of the right edge (near_right_edge)
  • Row is hard-wrapped (!self.row_wraps()WRAPLINE absent)
  • Next row exists (checked_add overflow-safe)

Guards are all O(1). Common case (short URL, soft-wrap, or URL not near edge) exits immediately at near_right_edge with zero additional allocations.

Continuation is rejected if the first char is uppercase (new-sentence guard) or whitespace (indented-block guard).

2. link_at_range newline stripping (terminal_model.rs)

Strips embedded \n/\r from the concatenated URL text. RFC 3986 URLs cannot contain raw newlines. All existing callers are URL-specific (guarded by GridHighlightedLink::Url). No-op for single-row URLs.

Behavior invariants

  1. URL ending near right edge of hard-wrapped row + valid continuation → full URL returned
  2. Existing soft-wrap detection unaffected (row_wraps() == true → probe does not fire)
  3. Uppercase-start continuation rejected (prevents false join with sentence starts)
  4. Whitespace-start continuation rejected
  5. Hovering on continuation row returns None (backward scan limitation — V1 scope)

Known limitation

URLs whose continuation begins with uppercase (e.g., /OAuth2/callback) are not extended. Deliberate tradeoff to avoid false joins with prose. V2 can relax this when continuation immediately follows /.

V1 scope boundary

Testing

cargo test -p warp --lib grid_handler_tests::test_url_extends_across_hard_wrap
cargo test -p warp --lib grid_handler_tests::test_url_hard_wrap_no_extend

4 new tests covering: extension across boundary, uppercase rejection, whitespace rejection, backward-scan limitation.

Existing test_find_url_line_wrapping (soft-wrap) passes unchanged.

Manual testing

  1. Run printf "See: https://auth.example.com/oauth/v2/authorize?client_id=app&state=abc123\r\n&redirect_uri=https%%3A%%2F%%2Fapp.example.com\r\n" in Warp
  2. Hover first row → full URL highlighted across both rows
  3. CMD+click → opens complete URL
  4. Hover second row → no highlight (V1 limitation, documented)

Some programs (e.g. kiro-cli) emit explicit \r\n, creating hard-wrapped
rows whose WRAPLINE flag is absent. The grapheme cursor in url_at_point
follows only soft wraps (Wrap::Soft), so it stops at hard-wrap row
boundaries and returns a truncated URL fragment when a URL overflows the
terminal width. CMD+click then silently opens the wrong address.

Two-part fix:

1. url_at_point (grid_handler.rs): after the main forward scan, if the
   detected URL ends near the right edge of a hard-wrapped row, scan the
   leading token of the following row. If it looks like a URL fragment
   (no URL separators, does not start with an uppercase letter) extend
   the Link range to include it.

2. link_at_range (terminal_model.rs): strip embedded \r/\n characters
   that appear when the URL range spans a hard-wrapped row boundary.
   RFC 3986 URLs cannot contain raw newlines, so this stripping is
   always correct.

The heuristic is conservative by design:
- Only fires when the URL ends within 4 columns of the right edge
- Requires the row to be hard-wrapped (WRAPLINE flag absent)
- Rejects continuations starting with uppercase (new sentence, not URL)
- Rejects continuations starting with whitespace (indented blocks)

Closes warpdotdev#11609
See also warpdotdev#6541 (OSC 8 hyperlinks — the clean upstream fix that would
supersede this heuristic once implemented)

Tests added:
- test_url_extends_across_hard_wrap_boundary
- test_url_hard_wrap_no_extend_for_uppercase_continuation
- test_url_hard_wrap_no_extend_for_space_continuation
@cla-bot cla-bot Bot added the cla-signed label May 23, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 23, 2026

@rndjams

This PR is not linked to an issue that is marked with ready-to-implement.

Issue-state enforcement details:

Readiness check:

To continue, link this PR to a same-repo issue such as Closes #123 in the PR description, and make sure that issue has ready-to-implement.

Powered by Oz

@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 23, 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.

@rndjams

This PR is not linked to an issue that is marked with ready-to-implement.

Issue-state enforcement details:

  • Associated same-repo issues checked: #11609

  • Required readiness label: ready-to-implement

Readiness check:

  • #11609: missing ready-to-implement; readiness labels present: none

To continue, link this PR to a same-repo issue such as Closes #123 in the PR description, and make sure that issue has ready-to-implement.

Powered by Oz

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Hi @rndjams — a reviewer requested changes on this PR and it hasn't had activity from you in 12 days. When you get a chance, please push updates or reply to the review so a reviewer can take another look. Without activity, this PR will be automatically closed after 30 days of inactivity.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 7, 2026

Hi @rndjams — a reviewer requested changes on this PR and it hasn't had activity from you in 14 days. When you get a chance, please push updates or reply to the review so a reviewer can take another look. Without activity, this PR will be automatically closed after 30 days of inactivity.

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.

URL soft-wrap: AI TUI output splits URLs across rows — CMD+click opens truncated fragment

1 participant