mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-11 22:00:41 -07:00
fix(cli): Polish shell autocomplete rendering to be a little more shell native feeling. (#20931)
This commit is contained in:
@@ -301,6 +301,27 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
const resetCommandSearchCompletionState =
|
||||
commandSearchCompletion.resetCompletionState;
|
||||
|
||||
const getActiveCompletion = useCallback(() => {
|
||||
if (commandSearchActive) return commandSearchCompletion;
|
||||
if (reverseSearchActive) return reverseSearchCompletion;
|
||||
return completion;
|
||||
}, [
|
||||
commandSearchActive,
|
||||
commandSearchCompletion,
|
||||
reverseSearchActive,
|
||||
reverseSearchCompletion,
|
||||
completion,
|
||||
]);
|
||||
|
||||
const activeCompletion = getActiveCompletion();
|
||||
const shouldShowSuggestions = activeCompletion.showSuggestions;
|
||||
|
||||
const {
|
||||
forceShowShellSuggestions,
|
||||
setForceShowShellSuggestions,
|
||||
isShellSuggestionsVisible,
|
||||
} = completion;
|
||||
|
||||
const showCursor = focus && isShellFocused && !isEmbeddedShellFocused;
|
||||
|
||||
// Notify parent component about escape prompt state changes
|
||||
@@ -363,7 +384,8 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
userMessages,
|
||||
onSubmit: handleSubmitAndClear,
|
||||
isActive:
|
||||
(!completion.showSuggestions || completion.suggestions.length === 1) &&
|
||||
(!(completion.showSuggestions && isShellSuggestionsVisible) ||
|
||||
completion.suggestions.length === 1) &&
|
||||
!shellModeActive,
|
||||
currentQuery: buffer.text,
|
||||
currentCursorOffset: buffer.getOffset(),
|
||||
@@ -595,9 +617,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
keyMatchers[Command.END](key);
|
||||
|
||||
const isSuggestionsNav =
|
||||
(completion.showSuggestions ||
|
||||
reverseSearchCompletion.showSuggestions ||
|
||||
commandSearchCompletion.showSuggestions) &&
|
||||
shouldShowSuggestions &&
|
||||
(keyMatchers[Command.COMPLETION_UP](key) ||
|
||||
keyMatchers[Command.COMPLETION_DOWN](key) ||
|
||||
keyMatchers[Command.EXPAND_SUGGESTION](key) ||
|
||||
@@ -612,6 +632,10 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
isHistoryNav || isCursorMovement || keyMatchers[Command.ESCAPE](key),
|
||||
);
|
||||
hasUserNavigatedSuggestions.current = false;
|
||||
|
||||
if (key.name !== 'tab') {
|
||||
setForceShowShellSuggestions(false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jacobr): this special case is likely not needed anymore.
|
||||
@@ -641,15 +665,25 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
const isPlainTab =
|
||||
key.name === 'tab' && !key.shift && !key.alt && !key.ctrl && !key.cmd;
|
||||
const hasTabCompletionInteraction =
|
||||
completion.showSuggestions ||
|
||||
(completion.showSuggestions && isShellSuggestionsVisible) ||
|
||||
Boolean(completion.promptCompletion.text) ||
|
||||
reverseSearchActive ||
|
||||
commandSearchActive;
|
||||
|
||||
if (isPlainTab && shellModeActive) {
|
||||
resetPlainTabPress();
|
||||
if (!completion.showSuggestions) {
|
||||
if (!shouldShowSuggestions) {
|
||||
setSuppressCompletion(false);
|
||||
if (completion.promptCompletion.text) {
|
||||
completion.promptCompletion.accept();
|
||||
return true;
|
||||
} else if (
|
||||
completion.suggestions.length > 0 &&
|
||||
!forceShowShellSuggestions
|
||||
) {
|
||||
setForceShowShellSuggestions(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (isPlainTab) {
|
||||
if (!hasTabCompletionInteraction) {
|
||||
@@ -752,7 +786,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
if (
|
||||
key.sequence === '!' &&
|
||||
buffer.text === '' &&
|
||||
!completion.showSuggestions
|
||||
!(completion.showSuggestions && isShellSuggestionsVisible)
|
||||
) {
|
||||
setShellModeActive(!shellModeActive);
|
||||
buffer.setText(''); // Clear the '!' from input
|
||||
@@ -791,15 +825,15 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
return true;
|
||||
}
|
||||
|
||||
if (shellModeActive) {
|
||||
setShellModeActive(false);
|
||||
if (completion.showSuggestions && isShellSuggestionsVisible) {
|
||||
completion.resetCompletionState();
|
||||
setExpandedSuggestionIndex(-1);
|
||||
resetEscapeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (completion.showSuggestions) {
|
||||
completion.resetCompletionState();
|
||||
setExpandedSuggestionIndex(-1);
|
||||
if (shellModeActive) {
|
||||
setShellModeActive(false);
|
||||
resetEscapeState();
|
||||
return true;
|
||||
}
|
||||
@@ -895,7 +929,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
completion.isPerfectMatch &&
|
||||
keyMatchers[Command.SUBMIT](key) &&
|
||||
recentUnsafePasteTime === null &&
|
||||
(!completion.showSuggestions ||
|
||||
(!(completion.showSuggestions && isShellSuggestionsVisible) ||
|
||||
(completion.activeSuggestionIndex <= 0 &&
|
||||
!hasUserNavigatedSuggestions.current))
|
||||
) {
|
||||
@@ -909,7 +943,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
return true;
|
||||
}
|
||||
|
||||
if (completion.showSuggestions) {
|
||||
if (completion.showSuggestions && isShellSuggestionsVisible) {
|
||||
if (completion.suggestions.length > 1) {
|
||||
if (keyMatchers[Command.COMPLETION_UP](key)) {
|
||||
completion.navigateUp();
|
||||
@@ -1007,7 +1041,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
if (
|
||||
key.name === 'tab' &&
|
||||
!key.shift &&
|
||||
!completion.showSuggestions &&
|
||||
!(completion.showSuggestions && isShellSuggestionsVisible) &&
|
||||
completion.promptCompletion.text
|
||||
) {
|
||||
completion.promptCompletion.accept();
|
||||
@@ -1190,6 +1224,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
focus,
|
||||
buffer,
|
||||
completion,
|
||||
setForceShowShellSuggestions,
|
||||
shellModeActive,
|
||||
setShellModeActive,
|
||||
onClearScreen,
|
||||
@@ -1221,6 +1256,9 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
registerPlainTabPress,
|
||||
resetPlainTabPress,
|
||||
toggleCleanUiDetailsVisible,
|
||||
shouldShowSuggestions,
|
||||
isShellSuggestionsVisible,
|
||||
forceShowShellSuggestions,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1346,14 +1384,6 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
]);
|
||||
|
||||
const { inlineGhost, additionalLines } = getGhostTextLines();
|
||||
const getActiveCompletion = () => {
|
||||
if (commandSearchActive) return commandSearchCompletion;
|
||||
if (reverseSearchActive) return reverseSearchCompletion;
|
||||
return completion;
|
||||
};
|
||||
|
||||
const activeCompletion = getActiveCompletion();
|
||||
const shouldShowSuggestions = activeCompletion.showSuggestions;
|
||||
|
||||
const useBackgroundColor = config.getUseBackgroundColor();
|
||||
const isLowColor = isLowColorDepth();
|
||||
|
||||
Reference in New Issue
Block a user