Skip to content

Support undercurl SGR styling#10560

Open
jbetala7 wants to merge 2 commits into
warpdotdev:masterfrom
jbetala7:fix/undercurl-5633
Open

Support undercurl SGR styling#10560
jbetala7 wants to merge 2 commits into
warpdotdev:masterfrom
jbetala7:fix/undercurl-5633

Conversation

@jbetala7
Copy link
Copy Markdown
Contributor

@jbetala7 jbetala7 commented May 9, 2026

Fixes #5633.

Summary

  • Parse SGR underline style subparameters for single, double, and curly underline, plus underline color (58) and reset (59).
  • Store underline color in terminal cells and flat scrollback style data.
  • Render curly underline decorations and use the SGR underline color when present.
  • Preserve undercurl/underline color in grid string serialization and underline ref-test data.

Verification

  • cargo check -p warp --lib
  • cargo test -p warp_terminal test_contains_cell_decorations
  • cargo test -p warp_terminal test_push_rows_with_color

Visual proof

Notes

  • Attempted cargo test -p warp test_parsing_undercurl_and_underline_color, but the local machine ran out of disk while compiling unrelated app test dependencies (lsp, ai, tantivy, warp_graphql) before the test could run.

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 9, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @jbetala7 on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 9, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 9, 2026

@jbetala7

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

@jbetala7
Copy link
Copy Markdown
Contributor Author

jbetala7 commented May 9, 2026

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label May 9, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 9, 2026

The cla-bot has been summoned, and re-checked this pull request!

oz-for-oss[bot]
oz-for-oss Bot previously requested changes May 9, 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 adds parsing, storage, rendering, and serialization support for SGR curly underline and underline colors.

Concerns

  • Curly underline positioning appears incorrect: the new y value is later offset by the decoration height again, which moves the wave too far above the cell bottom.
  • This is a user-visible terminal styling change, but the PR context does not include screenshots, a screen recording, or a successful app-level verification of the undercurl rendering. Manual testing is required for changes that can be manually tested. Please include screenshots or a screen recording that show it working end to end, or justify why manual testing is not possible.

Verdict

Found: 0 critical, 2 important, 0 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

Comment thread app/src/terminal/grid_renderer.rs Outdated
Comment on lines +2340 to +2341
thickness * 3.,
cell_size.y() - thickness * 3.,
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.

⚠️ [IMPORTANT] This y value is subtracted by the decoration height again when building origin, so curly underlines render too far above the cell bottom. Use the cell bottom as the baseline for this decoration.

Suggested change
thickness * 3.,
cell_size.y() - thickness * 3.,
thickness * 3.,
cell_size.y(),

@jbetala7
Copy link
Copy Markdown
Contributor Author

jbetala7 commented May 9, 2026

Addressed the requested undercurl positioning change in 38e2f1a3 by using cell_size.y() as the curly underline baseline, so the shared decoration origin applies the decoration-height offset once.

Verification run on the current head:

  • cargo fmt --check
  • git diff --check
  • cargo check -p warp --lib

I do not have a reliable app-level visual screenshot from this local environment. The broader app-level verification was previously blocked locally by resource/environment constraints while compiling unrelated app test dependencies, so I am noting that limitation here rather than attaching a misleading screenshot. The renderer-level positioning concern has been corrected in code and the current head now passes the checks above.

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 9, 2026

@jbetala7

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 9, 2026 22:49

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 adds SGR parsing, cell/scrollback storage, serialization, and rendering support for curly underline and underline color.

Concerns

  • No blocking correctness or security concerns found in the annotated diff.

Verdict

Found: 0 critical, 0 important, 0 suggestions

Approve

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 requested review from a team and lucieleblanc and removed request for a team May 9, 2026 22:49
Copy link
Copy Markdown
Contributor

@lucieleblanc lucieleblanc left a comment

Choose a reason for hiding this comment

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

Hi @jbetala7, thanks for taking on this issue. This is a big user-facing change so it needs a screen capture. Please attach a screen recording to the PR description in which the curly underline and underline color are shown working correctly, both in standard terminal blocks and in alt screen programs (full-pane terminal interfaces, like Neovim or another text editor with LSP). On MacOS, you can start a screen recording using cmd-shift-5.

Please remove the linter steps from the PR description. They are presubmit checks, not proof of correctness.

Feel free to comment or re-request review when ready and we'll take another look!

/// Zerowidth characters stored in this cell WITH the base character at the start. This helps
/// optimize reads on this data structure (we don't need to allocate a new string to join the
/// base character and zerowidth characters).
#[serde(default, skip_serializing_if = "Option::is_none")]
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.

Why did these serde annotations change? This is the kind of change that would be great to explain with an inline GitHub comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

They changed so CellExtra stays sparse now that the struct has three independent optional fields. underline_color can exist without zero-width text or an end-of-prompt marker, and existing CellExtra values can exist without an underline color. Without skip_serializing_if, those cases would serialize unrelated null keys and churn the stored/ref-test JSON; without default, omitted optional keys in older or sparse serialized payloads would not be handled explicitly. No behavior change was intended for the existing fields.

@jbetala7
Copy link
Copy Markdown
Contributor Author

jbetala7 commented May 11, 2026

Uploaded a cleaner final screen recording from the locally built PR branch (./target/debug/warp-oss, commit 38e2f1a3):

https://raw.githubusercontent.com/jbetala7/warp/proof-10560-undercurl-final/warp-undercurl-screen-recording.mov

I sampled the capture before posting it. It shows regular terminal output with curly underline plus underline color, then a full-screen/alternate-screen sequence using DEC 1049h/1049l with colored curly underline and underline color.

@lucieleblanc
Copy link
Copy Markdown
Contributor

I sampled the capture before posting it

The point of the screen capture is to show an end-to-end flow (seeing the cursor, typing, etc.). but there is no difference between this "sampled" clip and a series of static screenshots. I would encourage you to run this manually and record the full interaction 🙂 it's fine to have an LLM generate a helper script or other material that you use for the demo, but ultimately the screen recording should show a human using the feature, with typing/clicking, opening and closing programs, etc.

I'll be happy to review this again with an actual recording! Otherwise this will be on the back burner.

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.

Support for undercurl

2 participants