fix(ui): prevent useSlashCompletion effects from running during @ completion (#8986)

This commit is contained in:
Sandy Tao
2025-09-20 09:13:58 -07:00
committed by GitHub
parent 468db8730a
commit 2216856e3c
2 changed files with 51 additions and 2 deletions

View File

@@ -807,4 +807,47 @@ describe('useSlashCompletion', () => {
});
});
});
it('should not call shared callbacks when disabled', () => {
const mockSetSuggestions = vi.fn();
const mockSetIsLoadingSuggestions = vi.fn();
const mockSetIsPerfectMatch = vi.fn();
const slashCommands = [
createTestCommand({
name: 'help',
description: 'Show help',
}),
];
const { rerender } = renderHook(
({ enabled, query }) =>
useSlashCompletion({
enabled,
query,
slashCommands,
commandContext: mockCommandContext,
setSuggestions: mockSetSuggestions,
setIsLoadingSuggestions: mockSetIsLoadingSuggestions,
setIsPerfectMatch: mockSetIsPerfectMatch,
}),
{
initialProps: { enabled: false, query: '@src/file' },
},
);
// Clear any initial calls
mockSetSuggestions.mockClear();
mockSetIsLoadingSuggestions.mockClear();
mockSetIsPerfectMatch.mockClear();
// Change query while disabled (simulating @ completion typing)
rerender({ enabled: false, query: '@src/file.ts' });
rerender({ enabled: false, query: '@src/file.tsx' });
// Should not have called shared callbacks during @ completion typing
expect(mockSetSuggestions).not.toHaveBeenCalled();
expect(mockSetIsLoadingSuggestions).not.toHaveBeenCalled();
expect(mockSetIsPerfectMatch).not.toHaveBeenCalled();
});
});

View File

@@ -485,14 +485,20 @@ export function useSlashCompletion(props: UseSlashCompletionProps): {
);
const { isPerfectMatch } = usePerfectMatch(parserResult);
// Update external state - this is now much simpler and focused
// Clear internal state when disabled
useEffect(() => {
if (!enabled || query === null) {
if (!enabled) {
setSuggestions([]);
setIsLoadingSuggestions(false);
setIsPerfectMatch(false);
setCompletionStart(-1);
setCompletionEnd(-1);
}
}, [enabled, setSuggestions, setIsLoadingSuggestions, setIsPerfectMatch]);
// Update external state only when enabled
useEffect(() => {
if (!enabled || query === null) {
return;
}