Skip to content

Commit d19d7de

Browse files
committed
fix(git): add syntax highlighting to raw diff fallback lines
1 parent 4772d3d commit d19d7de

File tree

5 files changed

+83
-18
lines changed

5 files changed

+83
-18
lines changed

src/features/git/components/GitDiffViewer.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,9 @@ describe("GitDiffViewer", () => {
124124
expect(screen.queryByText("Diff unavailable.")).toBeNull();
125125
expect(screen.getByText("added line")).toBeTruthy();
126126
expect(screen.getByText("removed line")).toBeTruthy();
127+
128+
const rawLines = Array.from(document.querySelectorAll(".diff-viewer-raw-line"));
129+
expect(rawLines[1]?.className).toContain("diff-viewer-raw-line-add");
130+
expect(rawLines[2]?.className).toContain("diff-viewer-raw-line-del");
127131
});
128132
});

src/features/git/components/GitDiffViewer.utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ export function parseRawDiffLines(diff: string): ParsedDiffLine[] {
5555
});
5656
}
5757

58+
export function isFallbackRawDiffLineHighlightable(
59+
type: ParsedDiffLine["type"],
60+
) {
61+
return type === "add" || type === "del" || type === "context";
62+
}
63+
5864
export function calculateDiffStats(diffs: GitDiffViewerItem[]): DiffStats {
5965
let additions = 0;
6066
let deletions = 0;

src/features/git/components/GitDiffViewerDiffCard.tsx

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ import type {
1212
PullRequestReviewIntent,
1313
} from "../../../types";
1414
import { parseDiff, type ParsedDiffLine } from "../../../utils/diff";
15+
import { highlightLine, languageFromPath } from "../../../utils/syntax";
1516
import {
1617
DIFF_VIEWER_SCROLL_CSS,
1718
} from "../../design-system/diff/diffViewerTheme";
1819
import { splitPath } from "./GitDiffPanel.utils";
1920
import type { GitDiffViewerItem } from "./GitDiffViewer.types";
20-
import { normalizePatchName, parseRawDiffLines } from "./GitDiffViewer.utils";
21+
import {
22+
isFallbackRawDiffLineHighlightable,
23+
normalizePatchName,
24+
parseRawDiffLines,
25+
} from "./GitDiffViewer.utils";
2126

2227
type HoveredDiffLine =
2328
| {
@@ -117,6 +122,10 @@ export const DiffCard = memo(function DiffCard({
117122
[displayPath],
118123
);
119124
const displayDir = dir ? `${dir}/` : "";
125+
const fallbackLanguage = useMemo(
126+
() => languageFromPath(displayPath),
127+
[displayPath],
128+
);
120129

121130
const fileDiff = useMemo(() => {
122131
if (!entry.diff.trim()) {
@@ -287,14 +296,26 @@ export const DiffCard = memo(function DiffCard({
287296
</div>
288297
) : entry.diff.trim().length > 0 && parsedLines.length > 0 ? (
289298
<div className="diff-viewer-output diff-viewer-output-flat diff-viewer-output-raw">
290-
{parsedLines.map((line, index) => (
291-
<div
292-
key={index}
293-
className={`diff-viewer-raw-line diff-viewer-raw-line-${line.type}`}
294-
>
295-
{line.text}
296-
</div>
297-
))}
299+
{parsedLines.map((line, index) => {
300+
const highlighted = highlightLine(
301+
line.text,
302+
isFallbackRawDiffLineHighlightable(line.type)
303+
? fallbackLanguage
304+
: null,
305+
);
306+
307+
return (
308+
<div
309+
key={index}
310+
className={`diff-viewer-raw-line diff-viewer-raw-line-${line.type}`}
311+
>
312+
<span
313+
className="diff-line-content"
314+
dangerouslySetInnerHTML={{ __html: highlighted }}
315+
/>
316+
</div>
317+
);
318+
})}
298319
</div>
299320
) : (
300321
<div className="diff-viewer-placeholder">{placeholder}</div>

src/features/git/components/PierreDiffBlock.tsx

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ import { useMemo } from "react";
22
import { parsePatchFiles, type FileDiffMetadata } from "@pierre/diffs";
33
import { FileDiff, WorkerPoolContextProvider } from "@pierre/diffs/react";
44
import { parseDiff } from "../../../utils/diff";
5+
import { highlightLine, languageFromPath } from "../../../utils/syntax";
56
import { workerFactory } from "../../../utils/diffsWorker";
67
import {
78
DIFF_VIEWER_HIGHLIGHTER_OPTIONS,
89
DIFF_VIEWER_SCROLL_CSS,
910
} from "../../design-system/diff/diffViewerTheme";
10-
import { normalizePatchName, parseRawDiffLines } from "./GitDiffViewer.utils";
11+
import {
12+
isFallbackRawDiffLineHighlightable,
13+
normalizePatchName,
14+
parseRawDiffLines,
15+
} from "./GitDiffViewer.utils";
1116

1217
type PierreDiffBlockProps = {
1318
diff: string;
@@ -60,6 +65,10 @@ export function PierreDiffBlock({
6065
}
6166
return parseRawDiffLines(diff);
6267
}, [diff]);
68+
const fallbackLanguage = useMemo(
69+
() => languageFromPath(displayPath),
70+
[displayPath],
71+
);
6372

6473
const diffOptions = useMemo(
6574
() => ({
@@ -91,14 +100,26 @@ export function PierreDiffBlock({
91100
</div>
92101
) : (
93102
<div className="diff-viewer-output diff-viewer-output-flat diff-viewer-output-raw">
94-
{parsedLines.map((line, index) => (
95-
<div
96-
key={index}
97-
className={`diff-viewer-raw-line diff-viewer-raw-line-${line.type}`}
98-
>
99-
{line.text}
100-
</div>
101-
))}
103+
{parsedLines.map((line, index) => {
104+
const highlighted = highlightLine(
105+
line.text,
106+
isFallbackRawDiffLineHighlightable(line.type)
107+
? fallbackLanguage
108+
: null,
109+
);
110+
111+
return (
112+
<div
113+
key={index}
114+
className={`diff-viewer-raw-line diff-viewer-raw-line-${line.type}`}
115+
>
116+
<span
117+
className="diff-line-content"
118+
dangerouslySetInnerHTML={{ __html: highlighted }}
119+
/>
120+
</div>
121+
);
122+
})}
102123
</div>
103124
)}
104125
</WorkerPoolContextProvider>

src/styles/diff-viewer.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,19 @@
688688
white-space: pre-wrap;
689689
}
690690

691+
.diff-viewer-raw-line .diff-line-content {
692+
min-width: 0;
693+
white-space: pre-wrap;
694+
}
695+
696+
.diff-viewer-raw-line-add {
697+
background: rgba(46, 160, 67, 0.25);
698+
}
699+
700+
.diff-viewer-raw-line-del {
701+
background: rgba(248, 81, 73, 0.25);
702+
}
703+
691704
.diff-line-hunk {
692705
background: var(--surface-card-muted);
693706
color: var(--text-subtle);

0 commit comments

Comments
 (0)