fix(core): resolve infinite loop and improve editor selection flow

- Fixes an infinite loop when using 'Modify with Editor' without a configured editor.
- Implements interactive editor selection via a UI dialog.
- Returns to the previous confirmation prompt if selection is cancelled or fails.
- Simplifies editor availability logic and removes deprecated sync functions.

Fixes #7669
This commit is contained in:
ehedlund
2026-02-04 14:00:08 -05:00
parent 37dabd873a
commit 02fc2aaef2
7 changed files with 147 additions and 379 deletions

View File

@@ -524,12 +524,22 @@ export const AppContainer = (props: AppContainerProps) => {
refreshStatic();
}, [refreshStatic, isAlternateBuffer, app, config]);
const [editorError, setEditorError] = useState<string | null>(null);
const {
isEditorDialogOpen,
openEditorDialog,
handleEditorSelect,
exitEditorDialog,
} = useEditorSettings(settings, setEditorError, historyManager.addItem);
useEffect(() => {
coreEvents.on(CoreEvent.ExternalEditorClosed, handleEditorClose);
coreEvents.on(CoreEvent.RequestEditorSelection, openEditorDialog);
return () => {
coreEvents.off(CoreEvent.ExternalEditorClosed, handleEditorClose);
coreEvents.off(CoreEvent.RequestEditorSelection, openEditorDialog);
};
}, [handleEditorClose]);
}, [handleEditorClose, openEditorDialog]);
useEffect(() => {
if (
@@ -543,6 +553,9 @@ export const AppContainer = (props: AppContainerProps) => {
}
}, [bannerVisible, bannerText, settings, config, refreshStatic]);
const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } =
useSettingsCommand();
const {
isThemeDialogOpen,
openThemeDialog,
@@ -738,17 +751,6 @@ Logging in with Google... Restarting Gemini CLI to continue.
onAuthError,
]);
const [editorError, setEditorError] = useState<string | null>(null);
const {
isEditorDialogOpen,
openEditorDialog,
handleEditorSelect,
exitEditorDialog,
} = useEditorSettings(settings, setEditorError, historyManager.addItem);
const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } =
useSettingsCommand();
const { isModelDialogOpen, openModelDialog, closeModelDialog } =
useModelCommand();

View File

@@ -15,6 +15,8 @@ import {
allowEditorTypeInSandbox,
checkHasEditorType,
getEditorDisplayName,
coreEvents,
CoreEvent,
} from '@google/gemini-cli-core';
import type { UseHistoryManagerReturn } from './useHistoryManager.js';
@@ -66,6 +68,7 @@ export const useEditorSettings = (
);
setEditorError(null);
setIsEditorDialogOpen(false);
coreEvents.emit(CoreEvent.EditorSelected, { editor: editorType });
} catch (error) {
setEditorError(`Failed to set editor preference: ${error}`);
}
@@ -75,6 +78,7 @@ export const useEditorSettings = (
const exitEditorDialog = useCallback(() => {
setIsEditorDialogOpen(false);
coreEvents.emit(CoreEvent.EditorSelected, { editor: undefined });
}, []);
return {