fix(ui): Remove dead dirs state and unused hook parameter from InputPrompt (#2891)

* fix(ui): prevent useEffect from running every render in InputPrompt

getDirectories() returns a new array reference each call, causing the
useEffect dependency check to fail on every render. Move the call
inside the effect body and use stable dependencies [config, dirs] so
the effect only re-runs when they actually change.

* fix(ui): use serialized dep key for directory change detection

Move from [config, dirs] deps (both stable refs that miss external
changes) to a dirKey string (join of current directories). This
preserves the perf fix (no new array ref in deps) while still
detecting directory additions/removals from /add-dir etc.

* refactor(cli): remove unused dirs state from InputPrompt

The dirs parameter passed to useCommandCompletion() was never read
inside that hook, making the dirs state and sync effect in InputPrompt
dead code. Remove the parameter, the state, the effect, and all test
call-site args.
This commit is contained in:
chinesepowered 2026-04-08 07:18:22 -07:00 committed by GitHub
parent f296eb1a6d
commit 5a5a175f00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 0 additions and 43 deletions

View file

@ -849,7 +849,6 @@ describe('InputPrompt', () => {
// Verify useCompletion was called with correct signature
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -878,7 +877,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -907,7 +905,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -936,7 +933,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -965,7 +961,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -995,7 +990,6 @@ describe('InputPrompt', () => {
// Verify useCompletion was called with the buffer
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1024,7 +1018,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1054,7 +1047,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1084,7 +1076,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1114,7 +1105,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1144,7 +1134,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1176,7 +1165,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1206,7 +1194,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,
@ -1238,7 +1225,6 @@ describe('InputPrompt', () => {
expect(mockedUseCommandCompletion).toHaveBeenCalledWith(
mockBuffer,
['/test/project/src'],
path.join('test', 'project', 'src'),
mockSlashCommands,
mockCommandContext,

View file

@ -168,15 +168,6 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
}
}, []);
const [dirs, setDirs] = useState<readonly string[]>(
config.getWorkspaceContext().getDirectories(),
);
const dirsChanged = config.getWorkspaceContext().getDirectories();
useEffect(() => {
if (dirs.length !== dirsChanged.length) {
setDirs(dirsChanged);
}
}, [dirs.length, dirsChanged]);
const [reverseSearchActive, setReverseSearchActive] = useState(false);
const [commandSearchActive, setCommandSearchActive] = useState(false);
const [textBeforeReverseSearch, setTextBeforeReverseSearch] = useState('');
@ -190,7 +181,6 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
const completion = useCommandCompletion(
buffer,
dirs,
config.getTargetDir(),
slashCommands,
commandContext,

View file

@ -84,7 +84,6 @@ const setupMocks = ({
describe('useCommandCompletion', () => {
const mockCommandContext = {} as CommandContext;
const mockConfig = {} as Config;
const testDirs: string[] = [];
const testRootDir = '/';
// Helper to create real TextBuffer objects within renderHook
@ -114,7 +113,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest(''),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -139,7 +137,6 @@ describe('useCommandCompletion', () => {
const textBuffer = useTextBufferForTest('@file');
const completion = useCommandCompletion(
textBuffer,
testDirs,
testRootDir,
[],
mockCommandContext,
@ -172,7 +169,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('@files'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -200,7 +196,6 @@ describe('useCommandCompletion', () => {
renderHook(() =>
useCommandCompletion(
useTextBufferForTest(text),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -226,7 +221,6 @@ describe('useCommandCompletion', () => {
renderHook(() =>
useCommandCompletion(
useTextBufferForTest(text, cursorOffset),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -265,7 +259,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('/'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -286,7 +279,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('/'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -306,7 +298,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('/'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -332,7 +323,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('/'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -361,7 +351,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('/'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -398,7 +387,6 @@ describe('useCommandCompletion', () => {
const { result } = renderHook(() =>
useCommandCompletion(
useTextBufferForTest('/'),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -427,7 +415,6 @@ describe('useCommandCompletion', () => {
renderHook(() =>
useCommandCompletion(
useTextBufferForTest(text),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -455,7 +442,6 @@ describe('useCommandCompletion', () => {
renderHook(() =>
useCommandCompletion(
useTextBufferForTest(text),
testDirs,
testRootDir,
[],
mockCommandContext,
@ -484,7 +470,6 @@ describe('useCommandCompletion', () => {
const textBuffer = useTextBufferForTest(text);
const completion = useCommandCompletion(
textBuffer,
testDirs,
testRootDir,
[],
mockCommandContext,
@ -517,7 +502,6 @@ describe('useCommandCompletion', () => {
const textBuffer = useTextBufferForTest('/mem');
const completion = useCommandCompletion(
textBuffer,
testDirs,
testRootDir,
[],
mockCommandContext,
@ -547,7 +531,6 @@ describe('useCommandCompletion', () => {
const textBuffer = useTextBufferForTest('@src/fi');
const completion = useCommandCompletion(
textBuffer,
testDirs,
testRootDir,
[],
mockCommandContext,
@ -580,7 +563,6 @@ describe('useCommandCompletion', () => {
const textBuffer = useTextBufferForTest(text, cursorOffset);
const completion = useCommandCompletion(
textBuffer,
testDirs,
testRootDir,
[],
mockCommandContext,

View file

@ -39,7 +39,6 @@ export interface UseCommandCompletionReturn {
export function useCommandCompletion(
buffer: TextBuffer,
dirs: readonly string[],
cwd: string,
slashCommands: readonly SlashCommand[],
commandContext: CommandContext,