mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-12 12:26:57 -07:00
fix(cli): stabilize prompt layout to prevent jumping when typing (#21081)
This commit is contained in:
@@ -831,7 +831,7 @@ describe('Composer', () => {
|
|||||||
expect(lastFrame({ allowEmpty: true })).toContain('ShortcutsHint');
|
expect(lastFrame({ allowEmpty: true })).toContain('ShortcutsHint');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not show shortcuts hint immediately when buffer has text', async () => {
|
it('hides shortcuts hint when text is typed in buffer', async () => {
|
||||||
const uiState = createMockUIState({
|
const uiState = createMockUIState({
|
||||||
buffer: { text: 'hello' } as unknown as TextBuffer,
|
buffer: { text: 'hello' } as unknown as TextBuffer,
|
||||||
cleanUiDetailsVisible: false,
|
cleanUiDetailsVisible: false,
|
||||||
@@ -901,16 +901,6 @@ describe('Composer', () => {
|
|||||||
expect(lastFrame()).not.toContain('ShortcutsHint');
|
expect(lastFrame()).not.toContain('ShortcutsHint');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hides shortcuts hint when text is typed in buffer', async () => {
|
|
||||||
const uiState = createMockUIState({
|
|
||||||
buffer: { text: 'hello' } as unknown as TextBuffer,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { lastFrame } = await renderComposer(uiState);
|
|
||||||
|
|
||||||
expect(lastFrame()).not.toContain('ShortcutsHint');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('hides shortcuts hint while loading in minimal mode', async () => {
|
it('hides shortcuts hint while loading in minimal mode', async () => {
|
||||||
const uiState = createMockUIState({
|
const uiState = createMockUIState({
|
||||||
cleanUiDetailsVisible: false,
|
cleanUiDetailsVisible: false,
|
||||||
|
|||||||
@@ -171,10 +171,10 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
|||||||
return () => clearTimeout(timeout);
|
return () => clearTimeout(timeout);
|
||||||
}, [canShowShortcutsHint]);
|
}, [canShowShortcutsHint]);
|
||||||
|
|
||||||
|
const shouldReserveSpaceForShortcutsHint =
|
||||||
|
settings.merged.ui.showShortcutsHint && !hideShortcutsHintForSuggestions;
|
||||||
const showShortcutsHint =
|
const showShortcutsHint =
|
||||||
settings.merged.ui.showShortcutsHint &&
|
shouldReserveSpaceForShortcutsHint && showShortcutsHintDebounced;
|
||||||
!hideShortcutsHintForSuggestions &&
|
|
||||||
showShortcutsHintDebounced;
|
|
||||||
const showMinimalModeBleedThrough =
|
const showMinimalModeBleedThrough =
|
||||||
!hideUiDetailsForSuggestions && Boolean(minimalModeBleedThrough);
|
!hideUiDetailsForSuggestions && Boolean(minimalModeBleedThrough);
|
||||||
const showMinimalInlineLoading = !showUiDetails && showLoadingIndicator;
|
const showMinimalInlineLoading = !showUiDetails && showLoadingIndicator;
|
||||||
@@ -187,7 +187,7 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
|||||||
!showUiDetails &&
|
!showUiDetails &&
|
||||||
(showMinimalInlineLoading ||
|
(showMinimalInlineLoading ||
|
||||||
showMinimalBleedThroughRow ||
|
showMinimalBleedThroughRow ||
|
||||||
showShortcutsHint);
|
shouldReserveSpaceForShortcutsHint);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -249,6 +249,9 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
|||||||
marginTop={isNarrow ? 1 : 0}
|
marginTop={isNarrow ? 1 : 0}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
alignItems={isNarrow ? 'flex-start' : 'flex-end'}
|
alignItems={isNarrow ? 'flex-start' : 'flex-end'}
|
||||||
|
minHeight={
|
||||||
|
showUiDetails && shouldReserveSpaceForShortcutsHint ? 1 : 0
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{showUiDetails && showShortcutsHint && <ShortcutsHint />}
|
{showUiDetails && showShortcutsHint && <ShortcutsHint />}
|
||||||
</Box>
|
</Box>
|
||||||
@@ -304,11 +307,13 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{(showMinimalContextBleedThrough || showShortcutsHint) && (
|
{(showMinimalContextBleedThrough ||
|
||||||
|
shouldReserveSpaceForShortcutsHint) && (
|
||||||
<Box
|
<Box
|
||||||
marginTop={isNarrow && showMinimalBleedThroughRow ? 1 : 0}
|
marginTop={isNarrow && showMinimalBleedThroughRow ? 1 : 0}
|
||||||
flexDirection={isNarrow ? 'column' : 'row'}
|
flexDirection={isNarrow ? 'column' : 'row'}
|
||||||
alignItems={isNarrow ? 'flex-start' : 'flex-end'}
|
alignItems={isNarrow ? 'flex-start' : 'flex-end'}
|
||||||
|
minHeight={1}
|
||||||
>
|
>
|
||||||
{showMinimalContextBleedThrough && (
|
{showMinimalContextBleedThrough && (
|
||||||
<ContextUsageDisplay
|
<ContextUsageDisplay
|
||||||
@@ -317,18 +322,14 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
|||||||
terminalWidth={uiState.terminalWidth}
|
terminalWidth={uiState.terminalWidth}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showShortcutsHint && (
|
<Box
|
||||||
<Box
|
marginLeft={
|
||||||
marginLeft={
|
showMinimalContextBleedThrough && !isNarrow ? 1 : 0
|
||||||
showMinimalContextBleedThrough && !isNarrow ? 1 : 0
|
}
|
||||||
}
|
marginTop={showMinimalContextBleedThrough && isNarrow ? 1 : 0}
|
||||||
marginTop={
|
>
|
||||||
showMinimalContextBleedThrough && isNarrow ? 1 : 0
|
{showShortcutsHint && <ShortcutsHint />}
|
||||||
}
|
</Box>
|
||||||
>
|
|
||||||
<ShortcutsHint />
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user