diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 3ab0419618f..e22e6a7297d 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -432,31 +432,90 @@ export class DiffViewProvider { // Open new diff editor. return new Promise((resolve, reject) => { - const fileName = path.basename(uri.fsPath) - const fileExists = this.editType === "modify" - - const disposable = vscode.window.onDidChangeActiveTextEditor((editor) => { - if (editor && arePathsEqual(editor.document.uri.fsPath, uri.fsPath)) { - disposable.dispose() - resolve(editor) + ;(async () => { + const fileName = path.basename(uri.fsPath) + const fileExists = this.editType === "modify" + let timeoutId: NodeJS.Timeout | undefined + + console.log(`[DiffViewProvider] Attempting to open diff editor for: ${uri.fsPath}`) + + const checkAndResolve = () => { + for (const group of vscode.window.tabGroups.all) { + for (const tab of group.tabs) { + if ( + tab.input instanceof vscode.TabInputTextDiff && + tab.input?.original?.scheme === DIFF_VIEW_URI_SCHEME && + arePathsEqual(tab.input.modified.fsPath, uri.fsPath) + ) { + // Found the diff editor, now try to show it to get the TextEditor instance + vscode.window.showTextDocument(tab.input.modified, { preserveFocus: true }).then( + (editor) => { + console.log( + `[DiffViewProvider] Diff editor found and activated via tabGroups: ${editor.document.uri.fsPath}`, + ) + if (timeoutId) clearTimeout(timeoutId) + disposableTabGroup.dispose() + resolve(editor) + }, + (err) => { + console.error( + `[DiffViewProvider] Error showing text document after finding tab: ${err}`, + ) + if (timeoutId) clearTimeout(timeoutId) + disposableTabGroup.dispose() + reject( + new Error(`Failed to show diff editor after finding tab: ${err.message}`), + ) + }, + ) + return true + } + } + } + return false } - }) - - vscode.commands.executeCommand( - "vscode.diff", - vscode.Uri.parse(`${DIFF_VIEW_URI_SCHEME}:${fileName}`).with({ - query: Buffer.from(this.originalContent ?? "").toString("base64"), - }), - uri, - `${fileName}: ${fileExists ? "Original ↔ Roo's Changes" : "New File"} (Editable)`, - { preserveFocus: true }, - ) - // This may happen on very slow machines i.e. project idx. - setTimeout(() => { - disposable.dispose() - reject(new Error("Failed to open diff editor, please try again...")) - }, 10_000) + // Listen for changes in tab groups, which includes tabs moving between windows + const disposableTabGroup = vscode.window.tabGroups.onDidChangeTabGroups(() => { + console.log(`[DiffViewProvider] onDidChangeTabGroups fired. Checking for diff editor.`) + checkAndResolve() + }) + + vscode.commands + .executeCommand( + "vscode.diff", + vscode.Uri.parse(`${DIFF_VIEW_URI_SCHEME}:${fileName}`).with({ + query: Buffer.from(this.originalContent ?? "").toString("base64"), + }), + uri, + `${fileName}: ${fileExists ? "Original ↔ Roo's Changes" : "New File"} (Editable)`, + { preserveFocus: true }, + ) + .then( + async () => { + console.log(`[DiffViewProvider] vscode.diff command executed for: ${uri.fsPath}`) + // Give a brief moment for the editor to appear in tab groups + await new Promise((r) => setTimeout(r, 100)) + if (!checkAndResolve()) { + console.log( + `[DiffViewProvider] Diff editor not immediately found after command. Waiting for tab group changes.`, + ) + } + }, + (err) => { + console.error(`[DiffViewProvider] Error executing vscode.diff command: ${err}`) + if (timeoutId) clearTimeout(timeoutId) + disposableTabGroup.dispose() + reject(new Error(`Failed to open diff editor command: ${err.message}`)) + }, + ) + + timeoutId = setTimeout(() => { + console.log(`[DiffViewProvider] Diff editor open timeout triggered for: ${uri.fsPath}`) + disposableTabGroup.dispose() + reject(new Error("Failed to open diff editor, please try again...")) + }, 10_000) + })() }) } diff --git a/webview-ui/src/__tests__/example.spec.ts b/webview-ui/src/__tests__/example.spec.ts new file mode 100644 index 00000000000..e69de29bb2d