Skip to content

core/diff: per-kind line-number fg + side-targeted line color API#1013

Draft
kitlangton wants to merge 3 commits into
anomalyco:mainfrom
kitlangton:kit/diff-line-number-fg
Draft

core/diff: per-kind line-number fg + side-targeted line color API#1013
kitlangton wants to merge 3 commits into
anomalyco:mainfrom
kitlangton:kit/diff-line-number-fg

Conversation

@kitlangton
Copy link
Copy Markdown
Collaborator

Summary

Two small additions to the diff renderer, both motivated by real consumer pain:

1. Per-kind line-number foreground colors

Today every line-number digit in the gutter is painted with one lineNumberFg (default #888), even on + / rows where the sign glyph is already tinted green/red. This adds three optional overrides:

  • addedLineNumberFg
  • removedLineNumberFg
  • contextLineNumberFg

Each defaults to undefined (existing lineNumberFg remains the umbrella default), so behavior is unchanged unless a consumer opts in.

Underneath, LineColorConfig (the per-line override shape used by LineNumberRenderable) gains an optional fg?: string | RGBA so manual setLineColor() callers can also set the digit color, not just background.

before:                              after (with the new options set):
  41                                   41                       (gray)
  43 −  return greeting + name         43 −  return greeting…   (red)
  43 +  return `Hi, ${name}!`          43 +  return `Hi…`       (green)
  ↑                                    ↑
  digit always gray                    digit picks up kind color

2. Side-targeted line color API

The diff-level methods that paint individual lines now accept an optional side parameter:

type DiffSide = "left" | "right" | "both"

diff.setLineColor(line, color, side?)
diff.clearLineColor(line, side?)
diff.setLineColors(map, side?)
diff.clearAllLineColors(side?)
diff.highlightLines(start, end, color, side?)
diff.clearHighlightLines(start, end, side?)

Default is "both", so existing callers are byte-identical. New capability is "left" / "right" for split-view consumers — e.g. ghui, which currently has to do diff as unknown as DiffRenderableRuntimeSides and reach into the private leftSide / rightSide fields to highlight a single side for a PR comment anchor. With this PR, that hack collapses to a single public call.

Test plan

  • CI typecheck (local tsc --noEmit is clean for the modified files; pre-existing errors in unrelated tests/dev files remain unchanged)
  • bun run test src/renderables/Diff.test.ts src/renderables/__tests__/LineNumberRenderable.test.ts — could not run locally; my checkout's prebuilt @opentui/core-darwin-arm64 is missing the setClearOnShutdown symbol added in recent main, and a from-source rebuild fails with libc symbol errors (Zig 0.15.2 toolchain mismatch). Both predate this PR; CI / a fresh bun install should be fine.
  • Manual visual check via packages/examples/src/diff-demo.ts with the new options set, confirming digits in the + / rows pick up their tinted colors and that setLineColor(..., "left") only paints the left side in split view.

Marking as draft pending those last two checks.

kitlangton added 3 commits May 3, 2026 14:36
Adds three diff-level options (addedLineNumberFg, removedLineNumberFg,
contextLineNumberFg) so the gutter digits can be tinted per line kind
instead of being stuck at one color, and threads a new fg field through
LineColorConfig so manual setLineColor() callers can do the same.

The diff-level setLineColor / clearLineColor / setLineColors /
clearAllLineColors / highlightLines / clearHighlightLines methods now
take an optional side ("left" | "right" | "both", default "both"),
giving consumers a public way to target one half of a split view
without reaching into the private leftSide/rightSide fields.
Per-review cleanup. Three small helpers replace pasted blocks:

- buildLineConfig(kind) collapses the six near-identical
  { gutter, content, fg } construction sites in the unified and
  split builders into one place.
- forSide(side, fn) collapses the six side-filtered pass-through
  methods (setLineColor / clearLineColor / setLineColors /
  clearAllLineColors / highlightLines / clearHighlightLines).
- isLineColorConfig(value) replaces the inline triple-condition
  discriminator in parseLineColor.

Net effect: smaller diff and a single source of truth for the
per-kind config shape — adding another LineColorConfig field in
the future means touching one helper instead of six call sites.
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