Skip to content

An unchanged diff line takes only the last selector reading, so a construct spanning into a deleted line renders half-highlighted #4118

Description

@DmitrySharabin

Introduced by #4110. unchanged and ! blocks are named in both of diff's selectors, and documents.reverse() plus the done set make the last selector claim them — so an unchanged line always takes the inserted document's reading.

A construct opening on an unchanged line and closing on a deleted one then gets its two halves from different documents.

Repro

import { createInstance } from './tests/helper/prism-loader.js';

const prism = await createInstance(['diff', 'javascript', 'clike', 'markup']);

console.log(prism.highlight(' const t = `hi\n-  there`;\n const x = 1;', 'diff:javascript'));
v2   [deleted [prefix -]  there`[punctuation ;]                    ← nothing highlighted
new  [deleted [prefix -][template-string [string   there][template-punctuation `]][punctuation ;]

The closing half is a template-string; the opening backtick one line up is plain text. A closing token with no opener.

This one looks inherent

An unchanged line is genuinely in both versions of the file, and the two versions can tokenize it differently. Last-wins, first-wins, longest-wins — every assignment rule picks one document and leaves the other half disagreeing. There is no choice that makes both readings coherent, because the line has two truths.

It is milder than #4117: the damage stops at that container and does not run on. The trade is "no information" (v2) against "wrong-looking information" (now).

If it is worth addressing

When two documents produce different tokens for the same shared container, leave that container untokenized instead of picking a winner. That restores the v2 rendering exactly where the ambiguity exists, keeps the new behaviour everywhere else, and needs no new public API — cheaper than the separator concept #4117 would want.

Worth doing, or acceptable as-is?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions