Skip to content

Commit e9b8677

Browse files
authored
Multi File Diff Editor: Quickly Jump To Two Files Throws Error (fix microsoft#209892) (microsoft#227779)
1 parent 4e0d992 commit e9b8677

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

src/vs/workbench/browser/parts/editor/editorPanes.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export class EditorPanes extends Disposable {
8484
get activeEditorPane(): IVisibleEditorPane | null { return this._activeEditorPane as IVisibleEditorPane | null; }
8585

8686
private readonly editorPanes: EditorPane[] = [];
87+
private readonly mapEditorPaneToPendingSetInput = new Map<EditorPane, Promise<void>>();
8788

8889
private readonly activeEditorPaneDisposables = this._register(new DisposableStore());
8990
private pagePosition: IDomNodePagePosition | undefined;
@@ -409,11 +410,23 @@ export class EditorPanes extends Disposable {
409410
// If the input did not change, return early and only
410411
// apply the options unless the options instruct us to
411412
// force open it even if it is the same
412-
const inputMatches = editorPane.input?.matches(editor);
413+
let inputMatches = editorPane.input?.matches(editor);
413414
if (inputMatches && !options?.forceReload) {
414-
editorPane.setOptions(options);
415415

416-
return { changed: false, cancelled: false };
416+
// We have to await a pending `setInput()` call for this
417+
// pane before we can call into `setOptions()`, otherwise
418+
// we risk calling when the input is not yet fully applied.
419+
if (this.mapEditorPaneToPendingSetInput.has(editorPane)) {
420+
await this.mapEditorPaneToPendingSetInput.get(editorPane);
421+
}
422+
423+
// At this point, the input might have changed, so we check again
424+
inputMatches = editorPane.input?.matches(editor);
425+
if (inputMatches) {
426+
editorPane.setOptions(options);
427+
}
428+
429+
return { changed: false, cancelled: !inputMatches };
417430
}
418431

419432
// Start a new editor input operation to report progress
@@ -430,8 +443,10 @@ export class EditorPanes extends Disposable {
430443
// load (https://github.com/microsoft/vscode/issues/34697)
431444
editorPane.clearInput();
432445

433-
// Set the input to the editor pane
434-
await editorPane.setInput(editor, options, context, operation.token);
446+
// Set the input to the editor pane and keep track of it
447+
const pendingSetInput = editorPane.setInput(editor, options, context, operation.token);
448+
this.mapEditorPaneToPendingSetInput.set(editorPane, pendingSetInput);
449+
await pendingSetInput;
435450

436451
if (!operation.isCurrent()) {
437452
cancelled = true;
@@ -443,6 +458,9 @@ export class EditorPanes extends Disposable {
443458
throw error;
444459
}
445460
} finally {
461+
if (operation.isCurrent()) {
462+
this.mapEditorPaneToPendingSetInput.delete(editorPane);
463+
}
446464
operation.stop();
447465
}
448466

@@ -463,6 +481,9 @@ export class EditorPanes extends Disposable {
463481
this.safeRun(() => this._activeEditorPane?.clearInput());
464482
this.safeRun(() => this._activeEditorPane?.setVisible(false));
465483

484+
// Clear any pending setInput promise
485+
this.mapEditorPaneToPendingSetInput.delete(this._activeEditorPane);
486+
466487
// Remove editor pane from parent
467488
const editorPaneContainer = this._activeEditorPane.getContainer();
468489
if (editorPaneContainer) {

0 commit comments

Comments
 (0)