summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/cli/src/ui/components/messages/DiffRenderer.test.tsx50
-rw-r--r--packages/cli/src/ui/utils/CodeColorizer.tsx36
2 files changed, 72 insertions, 14 deletions
diff --git a/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx b/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx
index c6ecc279..8c2bba43 100644
--- a/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx
+++ b/packages/cli/src/ui/components/messages/DiffRenderer.test.tsx
@@ -208,4 +208,54 @@ index 123..789 100644
expect(output).toContain("21 + const anotherNew = 'test';");
expect(output).toContain("22 console.log('end of second hunk');");
});
+
+ it('should correctly render a diff with a SVN diff format', () => {
+ const newFileDiff = `
+fileDiff Index: file.txt
+===================================================================
+--- a/file.txt Current
++++ b/file.txt Proposed
+--- a/multi.js
++++ b/multi.js
+@@ -1,1 +1,1 @@
+-const oldVar = 1;
++const newVar = 1;
+@@ -20,1 +20,1 @@
+-const anotherOld = 'test';
++const anotherNew = 'test';
+\\ No newline at end of file
+`;
+ const { lastFrame } = render(
+ <DiffRenderer diffContent={newFileDiff} filename="TEST" />,
+ );
+ const output = lastFrame();
+
+ expect(output).toContain('1 - const oldVar = 1;');
+ expect(output).toContain('1 + const newVar = 1;');
+ expect(output).toContain('═');
+ expect(output).toContain("20 - const anotherOld = 'test';");
+ expect(output).toContain("20 + const anotherNew = 'test';");
+ });
+
+ it('should correctly render a new file with no file extension correctly', () => {
+ const newFileDiff = `
+fileDiff Index: Dockerfile
+===================================================================
+--- Dockerfile Current
++++ Dockerfile Proposed
+@@ -0,0 +1,3 @@
++FROM node:14
++RUN npm install
++RUN npm run build
+\\ No newline at end of file
+`;
+ const { lastFrame } = render(
+ <DiffRenderer diffContent={newFileDiff} filename="Dockerfile" />,
+ );
+ const output = lastFrame();
+
+ expect(output).toContain('1 FROM node:14');
+ expect(output).toContain('2 RUN npm install');
+ expect(output).toContain('3 RUN npm run build');
+ });
});
diff --git a/packages/cli/src/ui/utils/CodeColorizer.tsx b/packages/cli/src/ui/utils/CodeColorizer.tsx
index 441fc610..f3e7e8eb 100644
--- a/packages/cli/src/ui/utils/CodeColorizer.tsx
+++ b/packages/cli/src/ui/utils/CodeColorizer.tsx
@@ -66,6 +66,11 @@ function renderHastNode(
// Handle Root Node: Start recursion with initial inherited color
if (node.type === 'root') {
+ // Check if children array is empty - this happens when lowlight can't detect language – fallback to plain text
+ if (!node.children || node.children.length === 0) {
+ return null;
+ }
+
// Pass down the initial inheritedColor (likely undefined from the top call)
// Ensure child type matches expected HAST structure (RootContent is common)
return node.children?.map((child: RootContent, index: number) => (
@@ -105,21 +110,24 @@ export function colorizeCode(
return (
<Text>
- {lines.map((line, index) => (
- <Text key={index}>
- <Text color={activeTheme.colors.Gray}>
- {`${String(index + 1).padStart(padWidth, ' ')} `}
- </Text>
- <Text color={activeTheme.defaultColor}>
- {renderHastNode(
- getHighlightedLines(line),
- activeTheme,
- undefined,
- )}
+ {lines.map((line, index) => {
+ const renderedNode = renderHastNode(
+ getHighlightedLines(line),
+ activeTheme,
+ undefined,
+ );
+
+ const contentToRender = renderedNode !== null ? renderedNode : line;
+ return (
+ <Text key={index}>
+ <Text color={activeTheme.colors.Gray}>
+ {`${String(index + 1).padStart(padWidth, ' ')} `}
+ </Text>
+ <Text color={activeTheme.defaultColor}>{contentToRender}</Text>
+ {index < lines.length - 1 && '\n'}
</Text>
- {index < lines.length - 1 && '\n'}
- </Text>
- ))}
+ );
+ })}
</Text>
);
} catch (error) {