mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-06 16:17:34 -07:00
fix(cli): improve HalfLinePaddedBox rendering for Apple Terminal
This commit is contained in:
@@ -74,6 +74,7 @@ vi.mock('../ui/utils/terminalUtils.js', () => ({
|
||||
isLowColorDepth: vi.fn(() => false),
|
||||
getColorDepth: vi.fn(() => 24),
|
||||
isITerm2: vi.fn(() => false),
|
||||
isAppleTerminal: vi.fn(() => false),
|
||||
}));
|
||||
|
||||
type TerminalState = {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { renderWithProviders } from '../../../test-utils/render.js';
|
||||
import { HalfLinePaddedBox } from './HalfLinePaddedBox.js';
|
||||
import { Text, useIsScreenReaderEnabled } from 'ink';
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import { isITerm2 } from '../../utils/terminalUtils.js';
|
||||
import { isITerm2, isAppleTerminal } from '../../utils/terminalUtils.js';
|
||||
|
||||
vi.mock('ink', async () => {
|
||||
const actual = await vi.importActual('ink');
|
||||
@@ -25,34 +25,55 @@ describe('<HalfLinePaddedBox />', () => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('renders standard background and blocks when not iTerm2', async () => {
|
||||
it('renders standard background and blocks when not iTerm2 or Apple Terminal', async () => {
|
||||
vi.mocked(isITerm2).mockReturnValue(false);
|
||||
vi.mocked(isAppleTerminal).mockReturnValue(false);
|
||||
|
||||
const { lastFrame, unmount } = await renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<HalfLinePaddedBox backgroundBaseColor="blue" backgroundOpacity={0.5}>
|
||||
<Text>Content</Text>
|
||||
</HalfLinePaddedBox>,
|
||||
{ width: 10 },
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
await renderResult.waitUntilReady();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
|
||||
unmount();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('renders iTerm2-specific blocks when iTerm2 is detected', async () => {
|
||||
vi.mocked(isITerm2).mockReturnValue(true);
|
||||
vi.mocked(isAppleTerminal).mockReturnValue(false);
|
||||
|
||||
const { lastFrame, unmount } = await renderWithProviders(
|
||||
const renderResult = await renderWithProviders(
|
||||
<HalfLinePaddedBox backgroundBaseColor="blue" backgroundOpacity={0.5}>
|
||||
<Text>Content</Text>
|
||||
</HalfLinePaddedBox>,
|
||||
{ width: 10 },
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
await renderResult.waitUntilReady();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
|
||||
unmount();
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('renders Apple Terminal-specific blocks when Apple Terminal is detected', async () => {
|
||||
vi.mocked(isITerm2).mockReturnValue(false);
|
||||
vi.mocked(isAppleTerminal).mockReturnValue(true);
|
||||
|
||||
const renderResult = await renderWithProviders(
|
||||
<HalfLinePaddedBox backgroundBaseColor="blue" backgroundOpacity={0.5}>
|
||||
<Text>Content</Text>
|
||||
</HalfLinePaddedBox>,
|
||||
{ width: 10 },
|
||||
);
|
||||
|
||||
await renderResult.waitUntilReady();
|
||||
await expect(renderResult).toMatchSvgSnapshot();
|
||||
|
||||
renderResult.unmount();
|
||||
});
|
||||
|
||||
it('renders nothing when useBackgroundColor is false', async () => {
|
||||
|
||||
@@ -14,7 +14,11 @@ import {
|
||||
resolveColor,
|
||||
getSafeLowColorBackground,
|
||||
} from '../../themes/color-utils.js';
|
||||
import { isLowColorDepth, isITerm2 } from '../../utils/terminalUtils.js';
|
||||
import {
|
||||
isLowColorDepth,
|
||||
isITerm2,
|
||||
isAppleTerminal,
|
||||
} from '../../utils/terminalUtils.js';
|
||||
|
||||
export interface HalfLinePaddedBoxProps {
|
||||
/**
|
||||
@@ -108,6 +112,33 @@ const HalfLinePaddedBoxInternal: React.FC<HalfLinePaddedBoxProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
const isMacOSTerminal = isAppleTerminal();
|
||||
|
||||
if (isMacOSTerminal) {
|
||||
return (
|
||||
<Box
|
||||
width={terminalWidth}
|
||||
flexDirection="column"
|
||||
alignItems="stretch"
|
||||
minHeight={1}
|
||||
flexShrink={0}
|
||||
backgroundColor={backgroundColor}
|
||||
>
|
||||
<Box width={terminalWidth} flexDirection="row">
|
||||
<Text backgroundColor={terminalBg} color={backgroundColor}>
|
||||
{'▅'.repeat(terminalWidth)}
|
||||
</Text>
|
||||
</Box>
|
||||
{children}
|
||||
<Box width={terminalWidth} flexDirection="row">
|
||||
<Text color={terminalBg} backgroundColor={backgroundColor}>
|
||||
{'▄'.repeat(terminalWidth)}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
width={terminalWidth}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="110" height="71" viewBox="0 0 110 71">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="110" height="71" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<rect x="0" y="0" width="90" height="17" fill="#000000" />
|
||||
<text x="0" y="2" fill="#00007f" textLength="90" lengthAdjust="spacingAndGlyphs">▅▅▅▅▅▅▅▅▅▅</text>
|
||||
<rect x="0" y="17" width="90" height="17" fill="#00007f" />
|
||||
<text x="0" y="19" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Content </text>
|
||||
<rect x="0" y="34" width="90" height="17" fill="#00007f" />
|
||||
<text x="0" y="36" fill="#000000" textLength="90" lengthAdjust="spacingAndGlyphs">▄▄▄▄▄▄▄▄▄▄</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 882 B |
+12
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="110" height="71" viewBox="0 0 110 71">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="110" height="71" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<text x="0" y="2" fill="#00007f" textLength="90" lengthAdjust="spacingAndGlyphs">▄▄▄▄▄▄▄▄▄▄</text>
|
||||
<rect x="0" y="17" width="90" height="17" fill="#00007f" />
|
||||
<text x="0" y="19" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Content </text>
|
||||
<text x="0" y="36" fill="#00007f" textLength="90" lengthAdjust="spacingAndGlyphs">▀▀▀▀▀▀▀▀▀▀</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 755 B |
+14
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="110" height="71" viewBox="0 0 110 71">
|
||||
<style>
|
||||
text { font-family: Consolas, "Courier New", monospace; font-size: 14px; dominant-baseline: text-before-edge; white-space: pre; }
|
||||
</style>
|
||||
<rect width="110" height="71" fill="#000000" />
|
||||
<g transform="translate(10, 10)">
|
||||
<rect x="0" y="0" width="90" height="17" fill="#00007f" />
|
||||
<text x="0" y="2" fill="#000000" textLength="90" lengthAdjust="spacingAndGlyphs">▀▀▀▀▀▀▀▀▀▀</text>
|
||||
<rect x="0" y="17" width="90" height="17" fill="#00007f" />
|
||||
<text x="0" y="19" fill="#ffffff" textLength="90" lengthAdjust="spacingAndGlyphs">Content </text>
|
||||
<rect x="0" y="34" width="90" height="17" fill="#00007f" />
|
||||
<text x="0" y="36" fill="#000000" textLength="90" lengthAdjust="spacingAndGlyphs">▄▄▄▄▄▄▄▄▄▄</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 882 B |
@@ -1,10 +1,15 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`<HalfLinePaddedBox /> > renders Apple Terminal-specific blocks when Apple Terminal is detected 1`] = `
|
||||
"▅▅▅▅▅▅▅▅▅▅
|
||||
Content
|
||||
▄▄▄▄▄▄▄▄▄▄"
|
||||
`;
|
||||
|
||||
exports[`<HalfLinePaddedBox /> > renders iTerm2-specific blocks when iTerm2 is detected 1`] = `
|
||||
"▄▄▄▄▄▄▄▄▄▄
|
||||
Content
|
||||
▀▀▀▀▀▀▀▀▀▀
|
||||
"
|
||||
▀▀▀▀▀▀▀▀▀▀"
|
||||
`;
|
||||
|
||||
exports[`<HalfLinePaddedBox /> > renders nothing when screen reader is enabled 1`] = `
|
||||
@@ -17,9 +22,8 @@ exports[`<HalfLinePaddedBox /> > renders nothing when useBackgroundColor is fals
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<HalfLinePaddedBox /> > renders standard background and blocks when not iTerm2 1`] = `
|
||||
exports[`<HalfLinePaddedBox /> > renders standard background and blocks when not iTerm2 or Apple Terminal 1`] = `
|
||||
"▀▀▀▀▀▀▀▀▀▀
|
||||
Content
|
||||
▄▄▄▄▄▄▄▄▄▄
|
||||
"
|
||||
▄▄▄▄▄▄▄▄▄▄"
|
||||
`;
|
||||
|
||||
@@ -36,6 +36,13 @@ export function isITerm2(): boolean {
|
||||
return cachedIsITerm2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current terminal is macOS Terminal.
|
||||
*/
|
||||
export function isAppleTerminal(): boolean {
|
||||
return process.env['TERM_PROGRAM'] === 'Apple_Terminal';
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the cached iTerm2 detection value.
|
||||
* Primarily used for testing.
|
||||
|
||||
Reference in New Issue
Block a user