From 2e28bb90a00ad415d453a2ec868faa78679602f0 Mon Sep 17 00:00:00 2001
From: Miguel Solorio <miguelsolorio@google.com>
Date: Wed, 23 Jul 2025 15:39:22 -0700
Subject: Update diff colors (#4747)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
---
 .../src/ui/components/messages/DiffRenderer.tsx    | 50 +++++++++++++++-------
 1 file changed, 35 insertions(+), 15 deletions(-)

(limited to 'packages/cli/src/ui/components/messages/DiffRenderer.tsx')

diff --git a/packages/cli/src/ui/components/messages/DiffRenderer.tsx b/packages/cli/src/ui/components/messages/DiffRenderer.tsx
index db402517..7f130b3f 100644
--- a/packages/cli/src/ui/components/messages/DiffRenderer.tsx
+++ b/packages/cli/src/ui/components/messages/DiffRenderer.tsx
@@ -8,7 +8,7 @@ import React from 'react';
 import { Box, Text } from 'ink';
 import { Colors } from '../../colors.js';
 import crypto from 'crypto';
-import { colorizeCode } from '../../utils/CodeColorizer.js';
+import { colorizeCode, colorizeLine } from '../../utils/CodeColorizer.js';
 import { MaxSizedBox } from '../shared/MaxSizedBox.js';
 
 interface DiffLine {
@@ -157,7 +157,6 @@ export const DiffRenderer: React.FC<DiffRendererProps> = ({
       tabWidth,
       availableTerminalHeight,
       terminalWidth,
-      theme,
     );
   }
 
@@ -170,7 +169,6 @@ const renderDiffContent = (
   tabWidth = DEFAULT_TAB_WIDTH,
   availableTerminalHeight: number | undefined,
   terminalWidth: number,
-  theme?: import('../../themes/theme.js').Theme,
 ) => {
   // 1. Normalize whitespace (replace tabs with spaces) *before* further processing
   const normalizedLines = parsedLines.map((line) => ({
@@ -191,6 +189,18 @@ const renderDiffContent = (
     );
   }
 
+  const maxLineNumber = Math.max(
+    0,
+    ...displayableLines.map((l) => l.oldLine ?? 0),
+    ...displayableLines.map((l) => l.newLine ?? 0),
+  );
+  const gutterWidth = Math.max(1, maxLineNumber.toString().length);
+
+  const fileExtension = filename?.split('.').pop() || null;
+  const language = fileExtension
+    ? getLanguageFromExtension(fileExtension)
+    : null;
+
   // Calculate the minimum indentation across all displayable lines
   let baseIndentation = Infinity; // Start high to find the minimum
   for (const line of displayableLines) {
@@ -237,27 +247,25 @@ const renderDiffContent = (
         ) {
           acc.push(
             <Box key={`gap-${index}`}>
-              <Text wrap="truncate">{'═'.repeat(terminalWidth)}</Text>
+              <Text wrap="truncate" color={Colors.Gray}>
+                {'═'.repeat(terminalWidth)}
+              </Text>
             </Box>,
           );
         }
 
         const lineKey = `diff-line-${index}`;
         let gutterNumStr = '';
-        let color: string | undefined = undefined;
         let prefixSymbol = ' ';
-        let dim = false;
 
         switch (line.type) {
           case 'add':
             gutterNumStr = (line.newLine ?? '').toString();
-            color = theme?.colors?.AccentGreen || 'green';
             prefixSymbol = '+';
             lastLineNumber = line.newLine ?? null;
             break;
           case 'del':
             gutterNumStr = (line.oldLine ?? '').toString();
-            color = theme?.colors?.AccentRed || 'red';
             prefixSymbol = '-';
             // For deletions, update lastLineNumber based on oldLine if it's advancing.
             // This helps manage gaps correctly if there are multiple consecutive deletions
@@ -268,7 +276,6 @@ const renderDiffContent = (
             break;
           case 'context':
             gutterNumStr = (line.newLine ?? '').toString();
-            dim = true;
             prefixSymbol = ' ';
             lastLineNumber = line.newLine ?? null;
             break;
@@ -280,13 +287,26 @@ const renderDiffContent = (
 
         acc.push(
           <Box key={lineKey} flexDirection="row">
-            <Text color={Colors.Gray}>{gutterNumStr.padEnd(4)} </Text>
-            <Text color={color} dimColor={dim}>
-              {prefixSymbol}{' '}
-            </Text>
-            <Text color={color} dimColor={dim} wrap="wrap">
-              {displayContent}
+            <Text color={Colors.Gray}>
+              {gutterNumStr.padStart(gutterWidth)}{' '}
             </Text>
+            {line.type === 'context' ? (
+              <>
+                <Text>{prefixSymbol} </Text>
+                <Text wrap="wrap">
+                  {colorizeLine(displayContent, language)}
+                </Text>
+              </>
+            ) : (
+              <Text
+                backgroundColor={
+                  line.type === 'add' ? Colors.DiffAdded : Colors.DiffRemoved
+                }
+                wrap="wrap"
+              >
+                {prefixSymbol} {colorizeLine(displayContent, language)}
+              </Text>
+            )}
           </Box>,
         );
         return acc;
-- 
cgit v1.2.3

