mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-05 19:01:12 -07:00
feat(ui): add 'ctrl+o' hint to truncated content message (#20529)
This commit is contained in:
@@ -41,7 +41,9 @@ describe('<MaxSizedBox />', () => {
|
||||
</OverflowProvider>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... first 2 lines hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... first 2 lines hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -59,7 +61,9 @@ describe('<MaxSizedBox />', () => {
|
||||
</OverflowProvider>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... last 2 lines hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... last 2 lines hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -77,7 +81,9 @@ describe('<MaxSizedBox />', () => {
|
||||
</OverflowProvider>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... first 2 lines hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... first 2 lines hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -93,7 +99,9 @@ describe('<MaxSizedBox />', () => {
|
||||
</OverflowProvider>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... first 1 line hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... first 1 line hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -111,7 +119,9 @@ describe('<MaxSizedBox />', () => {
|
||||
</OverflowProvider>,
|
||||
);
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... first 7 lines hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... first 7 lines hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -197,7 +207,9 @@ describe('<MaxSizedBox />', () => {
|
||||
);
|
||||
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... first 21 lines hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... first 21 lines hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -218,7 +230,9 @@ describe('<MaxSizedBox />', () => {
|
||||
);
|
||||
|
||||
await waitUntilReady();
|
||||
expect(lastFrame()).toContain('... last 21 lines hidden ...');
|
||||
expect(lastFrame()).toContain(
|
||||
'... last 21 lines hidden (Ctrl+O to show) ...',
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
@@ -247,7 +261,9 @@ describe('<MaxSizedBox />', () => {
|
||||
const lastLine = lines[lines.length - 1];
|
||||
|
||||
// The last line should only contain the hidden indicator, no leaked content
|
||||
expect(lastLine).toMatch(/^\.\.\. last \d+ lines? hidden \.\.\.$/);
|
||||
expect(lastLine).toMatch(
|
||||
/^\.\.\. last \d+ lines? hidden \(Ctrl\+O to show\) \.\.\.$/,
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
@@ -9,6 +9,9 @@ import { useCallback, useEffect, useId, useRef, useState } from 'react';
|
||||
import { Box, Text, ResizeObserver, type DOMElement } from 'ink';
|
||||
import { theme } from '../../semantic-colors.js';
|
||||
import { useOverflowActions } from '../../contexts/OverflowContext.js';
|
||||
import { isNarrowWidth } from '../../utils/isNarrowWidth.js';
|
||||
import { Command } from '../../../config/keyBindings.js';
|
||||
import { formatCommand } from '../../utils/keybindingUtils.js';
|
||||
|
||||
/**
|
||||
* Minimum height for the MaxSizedBox component.
|
||||
@@ -84,6 +87,9 @@ export const MaxSizedBox: React.FC<MaxSizedBoxProps> = ({
|
||||
|
||||
const totalHiddenLines = hiddenLinesCount + additionalHiddenLinesCount;
|
||||
|
||||
const isNarrow = maxWidth !== undefined && isNarrowWidth(maxWidth);
|
||||
const showMoreKey = formatCommand(Command.SHOW_MORE_LINES);
|
||||
|
||||
useEffect(() => {
|
||||
if (totalHiddenLines > 0) {
|
||||
addOverflowingId?.(id);
|
||||
@@ -116,8 +122,9 @@ export const MaxSizedBox: React.FC<MaxSizedBoxProps> = ({
|
||||
>
|
||||
{totalHiddenLines > 0 && overflowDirection === 'top' && (
|
||||
<Text color={theme.text.secondary} wrap="truncate">
|
||||
... first {totalHiddenLines} line{totalHiddenLines === 1 ? '' : 's'}{' '}
|
||||
hidden ...
|
||||
{isNarrow
|
||||
? `... ${totalHiddenLines} hidden (${showMoreKey}) ...`
|
||||
: `... first ${totalHiddenLines} line${totalHiddenLines === 1 ? '' : 's'} hidden (${showMoreKey} to show) ...`}
|
||||
</Text>
|
||||
)}
|
||||
<Box
|
||||
@@ -137,8 +144,9 @@ export const MaxSizedBox: React.FC<MaxSizedBoxProps> = ({
|
||||
</Box>
|
||||
{totalHiddenLines > 0 && overflowDirection === 'bottom' && (
|
||||
<Text color={theme.text.secondary} wrap="truncate">
|
||||
... last {totalHiddenLines} line{totalHiddenLines === 1 ? '' : 's'}{' '}
|
||||
hidden ...
|
||||
{isNarrow
|
||||
? `... ${totalHiddenLines} hidden (${showMoreKey}) ...`
|
||||
: `... last ${totalHiddenLines} line${totalHiddenLines === 1 ? '' : 's'} hidden (${showMoreKey} to show) ...`}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`<MaxSizedBox /> > accounts for additionalHiddenLinesCount 1`] = `
|
||||
"... first 7 lines hidden ...
|
||||
"... first 7 lines hidden (Ctrl+O to show) ...
|
||||
Line 3
|
||||
"
|
||||
`;
|
||||
@@ -16,12 +16,12 @@ Line 6
|
||||
Line 7
|
||||
Line 8
|
||||
Line 9
|
||||
... last 21 lines hidden ...
|
||||
... last 21 lines hidden (Ctrl+O to show) ...
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<MaxSizedBox /> > clips a long single text child from the top 1`] = `
|
||||
"... first 21 lines hidden ...
|
||||
"... first 21 lines hidden (Ctrl+O to show) ...
|
||||
Line 22
|
||||
Line 23
|
||||
Line 24
|
||||
@@ -39,7 +39,7 @@ exports[`<MaxSizedBox /> > does not leak content after hidden indicator with bot
|
||||
|
||||
- Step 1: Do something important
|
||||
- Step 2: Do something important
|
||||
... last 18 lines hidden ...
|
||||
... last 18 lines hidden (Ctrl+O to show) ...
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -58,12 +58,12 @@ Line 3 direct child
|
||||
|
||||
exports[`<MaxSizedBox /> > hides lines at the end when content exceeds maxHeight and overflowDirection is bottom 1`] = `
|
||||
"Line 1
|
||||
... last 2 lines hidden ...
|
||||
... last 2 lines hidden (Ctrl+O to show) ...
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<MaxSizedBox /> > hides lines when content exceeds maxHeight 1`] = `
|
||||
"... first 2 lines hidden ...
|
||||
"... first 2 lines hidden (Ctrl+O to show) ...
|
||||
Line 3
|
||||
"
|
||||
`;
|
||||
@@ -74,13 +74,13 @@ exports[`<MaxSizedBox /> > renders children without truncation when they fit 1`]
|
||||
`;
|
||||
|
||||
exports[`<MaxSizedBox /> > shows plural "lines" when more than one line is hidden 1`] = `
|
||||
"... first 2 lines hidden ...
|
||||
"... first 2 lines hidden (Ctrl+O to show) ...
|
||||
Line 3
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<MaxSizedBox /> > shows singular "line" when exactly one line is hidden 1`] = `
|
||||
"... first 1 line hidden ...
|
||||
"... first 1 line hidden (Ctrl+O to show) ...
|
||||
Line 1
|
||||
"
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user