mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
Fix code colorizer ansi escape bug. (#21321)
This commit is contained in:
@@ -50,4 +50,36 @@ describe('colorizeCode', () => {
|
|||||||
expect(lastFrame()).toMatch(/line 1\s*\n\s*\n\s*line 3/);
|
expect(lastFrame()).toMatch(/line 1\s*\n\s*\n\s*line 3/);
|
||||||
unmount();
|
unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not let colors from ansi escape codes leak into colorized code', async () => {
|
||||||
|
const code = 'line 1\n\x1b[41mline 2 with red background\x1b[0m\nline 3';
|
||||||
|
const settings = new LoadedSettings(
|
||||||
|
{ path: '', settings: {}, originalSettings: {} },
|
||||||
|
{ path: '', settings: {}, originalSettings: {} },
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
settings: { ui: { useAlternateBuffer: true, showLineNumbers: false } },
|
||||||
|
originalSettings: {
|
||||||
|
ui: { useAlternateBuffer: true, showLineNumbers: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ path: '', settings: {}, originalSettings: {} },
|
||||||
|
true,
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = colorizeCode({
|
||||||
|
code,
|
||||||
|
language: 'javascript',
|
||||||
|
maxWidth: 80,
|
||||||
|
settings,
|
||||||
|
hideLineNumbers: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderResult = renderWithProviders(<>{result}</>);
|
||||||
|
await renderResult.waitUntilReady();
|
||||||
|
|
||||||
|
await expect(renderResult).toMatchSvgSnapshot();
|
||||||
|
renderResult.unmount();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import type {
|
|||||||
ElementContent,
|
ElementContent,
|
||||||
RootContent,
|
RootContent,
|
||||||
} from 'hast';
|
} from 'hast';
|
||||||
|
import stripAnsi from 'strip-ansi';
|
||||||
import { themeManager } from '../themes/theme-manager.js';
|
import { themeManager } from '../themes/theme-manager.js';
|
||||||
import type { Theme } from '../themes/theme.js';
|
import type { Theme } from '../themes/theme.js';
|
||||||
import {
|
import {
|
||||||
@@ -98,16 +99,17 @@ function highlightAndRenderLine(
|
|||||||
theme: Theme,
|
theme: Theme,
|
||||||
): React.ReactNode {
|
): React.ReactNode {
|
||||||
try {
|
try {
|
||||||
|
const strippedLine = stripAnsi(line);
|
||||||
const getHighlightedLine = () =>
|
const getHighlightedLine = () =>
|
||||||
!language || !lowlight.registered(language)
|
!language || !lowlight.registered(language)
|
||||||
? lowlight.highlightAuto(line)
|
? lowlight.highlightAuto(strippedLine)
|
||||||
: lowlight.highlight(language, line);
|
: lowlight.highlight(language, strippedLine);
|
||||||
|
|
||||||
const renderedNode = renderHastNode(getHighlightedLine(), theme, undefined);
|
const renderedNode = renderHastNode(getHighlightedLine(), theme, undefined);
|
||||||
|
|
||||||
return renderedNode !== null ? renderedNode : line;
|
return renderedNode !== null ? renderedNode : strippedLine;
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
return line;
|
return stripAnsi(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +240,7 @@ export function colorizeCode({
|
|||||||
<Text color={activeTheme.defaultColor}>{`${index + 1}`}</Text>
|
<Text color={activeTheme.defaultColor}>{`${index + 1}`}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<Text color={activeTheme.colors.Gray}>{line}</Text>
|
<Text color={activeTheme.colors.Gray}>{stripAnsi(line)}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="71" viewBox="0 0 920 71">
|
||||||
|
<style>
|
||||||
|
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||||
|
</style>
|
||||||
|
<rect width="920" height="71" fill="#000000" />
|
||||||
|
<g transform="translate(10, 10)">
|
||||||
|
<text x="0" y="2" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">line </text>
|
||||||
|
<text x="45" y="2" fill="#a6e3a1" textLength="9" lengthAdjust="spacingAndGlyphs">1</text>
|
||||||
|
<text x="0" y="19" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">line </text>
|
||||||
|
<text x="45" y="19" fill="#a6e3a1" textLength="9" lengthAdjust="spacingAndGlyphs">2</text>
|
||||||
|
<text x="63" y="19" fill="#89b4fa" textLength="36" lengthAdjust="spacingAndGlyphs">with</text>
|
||||||
|
<text x="99" y="19" fill="#ffffff" textLength="801" lengthAdjust="spacingAndGlyphs"> red background </text>
|
||||||
|
<text x="0" y="36" fill="#ffffff" textLength="45" lengthAdjust="spacingAndGlyphs">line </text>
|
||||||
|
<text x="45" y="36" fill="#a6e3a1" textLength="9" lengthAdjust="spacingAndGlyphs">3</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`colorizeCode > does not let colors from ansi escape codes leak into colorized code 1`] = `
|
||||||
|
"line 1
|
||||||
|
line 2 with red background
|
||||||
|
line 3"
|
||||||
|
`;
|
||||||
Reference in New Issue
Block a user