Skip to content

Highlighter: Implement syntax-highlighted diff rendering - #2035

Merged
marcoroth merged 3 commits into
mainfrom
highlighter-diff-view
Aug 6, 2026
Merged

marcoroth merged 3 commits into
mainfrom
highlighter-diff-view

Conversation

@marcoroth

@marcoroth marcoroth commented Aug 6, 2026 •

Copy link
Copy Markdown
Owner

This pull request adds a diff view to the Highlighter, so a change between two versions of a template can be rendered with the same syntax highlighting, gutter and theming as the rest of the package. The motivating case is previewing what a Linter autocorrection would do, which currently has no way to be shown.

The renderer computes hunks itself rather than taking a pre-formatted diff, highlights both sides, and marks the characters that actually changed within each line:

app/views/gems/index.html.erb

      1 │ <div id="gems">
  -   2 │   <span class='card'>Hello</span>
  +     │   <span class="card">Hello</span>
      3 │   <img src="a.png">
      4 │ </div>
CleanShot 2026-08-06 at 03 06 02@2x

Options

auto collapses a pair only where that reads better, and only when color is on. A pure insertion or deletion is the clearest case, because the composite is exactly the line as it exists in one of the two versions, with the inserted part tinted, nothing synthetic:

  ±   2 │   <img src="a.png" alt="">

A genuine replacement produces text that appears in neither version, so it collapses only while the change stays under 24 characters a side, stays a minority of the line, and still fits the available width. Collapsing a line only to have it truncated would trade a line of height for a loss of content.

With NO_COLOR set nothing collapses, including insertions. The composite above would still be a valid line, but without the tint it no longer shows which part was added, so the stacked pair carries strictly more information:

  -   2 │   <img src="a.png">
  +     │   <img src="a.png" alt="">

The split layout gives each column its own numbering, since there a column is one version of the file and the ambiguity that motivates the blank added numbers does not exist:

      1 │ <div>                          ┃       1 │ <div>
  -   2 │   <SPAN>restructured</SPAN>    ┃   +   2 │   <section>
        │                                ┃   +   3 │     <span>restructured</span>
        │                                ┃   +   4 │   </section>
      3 │   <p>untouched</p>             ┃       5 │   <p>untouched</p>

It falls back to unified when the terminal cannot give each column readable width.

On the command line

herb-highlight diff takes two files:

herb-highlight diff before.html.erb after.html.erb

It also renders a diff that was produced elsewhere, read from an argument or from stdin, following the same rule as herb-format: with no argument and something piped in, stdin is used.

git diff -- app/views | herb-highlight diff

The input may be unified diff text as produced by git diff, which parseUnifiedDiff() turns into hunks, or JSON as {"original": "...", "modified": "..."} or {"hunks": [...]}.

Follow up work: wiring this into the Linter CLI in #1572.

@github-actions github-actions Bot added typescript TypeScript source across the javascript/ packages highlighter @herb-tools/highlighter syntax highlighting and diagnostic rendering labels Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

🌿 Interactive Playground and Documentation Preview

A preview deployment has been built for this pull request. Try out the changes live in the interactive playground:


🌱 Grown from commit 1e64ade


✅ Preview deployment has been cleaned up.

@pkg-pr-new

pkg-pr-new Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
npx https://pkg.pr.new/@herb-tools/formatter@2035
npx https://pkg.pr.new/@herb-tools/language-server@2035
npx https://pkg.pr.new/@herb-tools/linter@2035

commit: 1e64ade

@marcoroth
marcoroth marked this pull request as ready for review August 6, 2026 01:30
@marcoroth marcoroth added this to the v0.11.0 milestone Aug 6, 2026
@marcoroth
marcoroth merged commit 88cdf79 into main Aug 6, 2026
22 checks passed
@marcoroth
marcoroth deleted the highlighter-diff-view branch August 6, 2026 01:50
marcoroth added a commit that referenced this pull request Aug 6, 2026
…tput (#1572)

This pull request adds a `--show-fix-diff` flag that previews what
`--fix` would change, without changing anything, so a correctable
offense can be inspected before it is applied.

The `[Correctable]` tag already tells you a fix exists, but not what it
does. Each correctable offense now gets a syntax highlighted diff
underneath it, rendered by the diff view from #2035, with the characters
that would actually change picked out:

```
[warning] Attribute `class` uses single quotes. Prefer double quotes for HTML attribute values: `class="card"`. (html-attribute-double-quotes) [Correctable]

index.html.erb:2:14

      1 │ <div id="gems">
  →   2 │   <SPAN class='card'>Hello</SPAN>
        │               ~~~~~~
      3 │ </div>


        Running --fix would correct this to:

        index.html.erb

              1 │ <div id="gems">
          -   2 │   <SPAN class='card'>Hello</SPAN>
          +     │   <SPAN class="card">Hello</SPAN>
              3 │ </div>
```

The heading names the flag that would apply it, rather than reading as
something that already happened. Previews are computed with unsafe fixes
included, so an offense that needs `--fix-unsafely` says so instead of
implying plain `--fix` would handle it.


<img width="2454" height="1380" alt="CleanShot 2026-08-06 at 03 43
25@2x"
src="https://github.com/user-attachments/assets/ae4e9859-b98d-4497-88fa-2d10fa54fdd3"
/>

<img width="3597" height="2024" alt="CleanShot 2026-08-06 at 03 43
02@2x"
src="https://github.com/user-attachments/assets/869f4c98-11e6-4755-8536-f724af4fa05b"
/>

This branch was successfully deployed

1 active deployment
herb-tools (Preview) — 1e64ade5 Deployed Aug 6, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

highlighter @herb-tools/highlighter syntax highlighting and diagnostic rendering typescript TypeScript source across the javascript/ packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant