diff --git a/src/sql/workbench/contrib/editorReplacement/common/editorReplacerContribution.ts b/src/sql/workbench/contrib/editorReplacement/common/editorReplacerContribution.ts index 34f8e72072..bf24e9f5c2 100644 --- a/src/sql/workbench/contrib/editorReplacement/common/editorReplacerContribution.ts +++ b/src/sql/workbench/contrib/editorReplacement/common/editorReplacerContribution.ts @@ -19,6 +19,7 @@ import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/u import { isThenable } from 'vs/base/common/async'; import { withNullAsUndefined } from 'vs/base/common/types'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; +import { mixin } from 'vs/base/common/objects'; const languageAssociationRegistry = Registry.as(LanguageAssociationExtensions.LanguageAssociations); @@ -69,7 +70,16 @@ export class EditorReplacementContribution implements IWorkbenchContribution { editor.setMode(defaultInputCreator[0]); const newInput = defaultInputCreator[1].convertInput(editor); if (newInput) { - return { override: isThenable(newInput) ? newInput.then(input => this.editorService.openEditor(input ?? editor, options, group)) : this.editorService.openEditor(newInput, options, group) }; + return { + // If the new input is a thenable which resolves to undefined (no input to convert) + // then don't allow further overriding since otherwise we could get in an infinite loop + // (openEditor calls onEditorOpening handler and we keep repeating this process). This + // is replicating the behavior for the non-Thenable returns where we just let the openEditor + // continue on + override: isThenable(newInput) ? + newInput.then(input => this.editorService.openEditor(input ?? editor, mixin(options, { override: input ? options?.override : false }), group)) : + this.editorService.openEditor(newInput, options, group) + }; } } } else { @@ -77,7 +87,16 @@ export class EditorReplacementContribution implements IWorkbenchContribution { if (inputCreator) { const newInput = inputCreator.convertInput(editor); if (newInput) { - return { override: isThenable(newInput) ? newInput.then(input => this.editorService.openEditor(input ?? editor, options, group)) : this.editorService.openEditor(newInput, options, group) }; + return { + // If the new input is a thenable which resolves to undefined (no input to convert) + // then don't allow further overriding since otherwise we could get in an infinite loop + // (openEditor calls onEditorOpening handler and we keep repeating this process). This + // is replicating the behavior for the non-Thenable returns where we just let the openEditor + // continue on + override: isThenable(newInput) ? + newInput.then(input => this.editorService.openEditor(input ?? editor, mixin(options, { override: input ? options?.override : false }), group)) + : this.editorService.openEditor(newInput, options, group) + }; } } }