mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-06 11:21:15 -07:00
fix(cli): disable auto-completion on Shift+Tab to preserve mode cycling (#19451)
This commit is contained in:
@@ -1221,6 +1221,36 @@ describe('InputPrompt', () => {
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should NOT autocomplete on Shift+Tab', async () => {
|
||||
const suggestion = { label: 'about', value: 'about' };
|
||||
|
||||
mockedUseCommandCompletion.mockReturnValue({
|
||||
...mockCommandCompletion,
|
||||
showSuggestions: true,
|
||||
suggestions: [suggestion],
|
||||
activeSuggestionIndex: 0,
|
||||
getCompletedText: vi.fn().mockReturnValue('/about'),
|
||||
});
|
||||
|
||||
props.buffer.setText('/ab');
|
||||
props.buffer.lines = ['/ab'];
|
||||
props.buffer.cursor = [0, 3];
|
||||
|
||||
const { stdin, unmount } = renderWithProviders(<InputPrompt {...props} />, {
|
||||
uiActions,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\x1b[Z'); // Shift+Tab
|
||||
});
|
||||
|
||||
// We need to wait a bit to ensure handleAutocomplete was NOT called
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
expect(mockCommandCompletion.handleAutocomplete).not.toHaveBeenCalled();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should autocomplete custom commands from .toml files on Enter', async () => {
|
||||
const customCommand: SlashCommand = {
|
||||
name: 'find-capital',
|
||||
@@ -2659,6 +2689,38 @@ describe('InputPrompt', () => {
|
||||
unmount();
|
||||
}, 15000);
|
||||
|
||||
it('should NOT autocomplete on Shift+Tab in reverse search', async () => {
|
||||
const mockHandleAutocomplete = vi.fn();
|
||||
|
||||
mockedUseReverseSearchCompletion.mockReturnValue({
|
||||
...mockReverseSearchCompletion,
|
||||
suggestions: [{ label: 'echo hello', value: 'echo hello' }],
|
||||
showSuggestions: true,
|
||||
activeSuggestionIndex: 0,
|
||||
handleAutocomplete: mockHandleAutocomplete,
|
||||
});
|
||||
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
{
|
||||
uiActions,
|
||||
},
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\x12'); // Ctrl+R
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\x1b[Z'); // Shift+Tab
|
||||
});
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
expect(mockHandleAutocomplete).not.toHaveBeenCalled();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('submits the highlighted entry on Enter and exits reverse-search', async () => {
|
||||
// Mock the reverse search completion to return suggestions
|
||||
mockedUseReverseSearchCompletion.mockReturnValue({
|
||||
@@ -3035,6 +3097,39 @@ describe('InputPrompt', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it('should NOT accept ghost text on Shift+Tab', async () => {
|
||||
const mockAccept = vi.fn();
|
||||
mockedUseCommandCompletion.mockReturnValue({
|
||||
...mockCommandCompletion,
|
||||
showSuggestions: false,
|
||||
suggestions: [],
|
||||
promptCompletion: {
|
||||
text: 'ghost text',
|
||||
accept: mockAccept,
|
||||
clear: vi.fn(),
|
||||
isLoading: false,
|
||||
isActive: true,
|
||||
markSelected: vi.fn(),
|
||||
},
|
||||
});
|
||||
|
||||
const { stdin, unmount } = renderWithProviders(
|
||||
<InputPrompt {...props} />,
|
||||
{
|
||||
uiActions,
|
||||
},
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
stdin.write('\x1b[Z'); // Shift+Tab
|
||||
});
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
expect(mockAccept).not.toHaveBeenCalled();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should not reveal clean UI details on Shift+Tab when hidden', async () => {
|
||||
mockedUseCommandCompletion.mockReturnValue({
|
||||
...mockCommandCompletion,
|
||||
|
||||
@@ -975,6 +975,7 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
|
||||
// Handle Tab key for ghost text acceptance
|
||||
if (
|
||||
key.name === 'tab' &&
|
||||
!key.shift &&
|
||||
!completion.showSuggestions &&
|
||||
completion.promptCompletion.text
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user