Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 79 additions & 28 deletions src/integrations/editor/DiffViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,7 @@ export class DiffViewProvider {
// Remove only the directories we created, in reverse order.
for (let i = this.createdDirs.length - 1; i >= 0; i--) {
await fs.rmdir(this.createdDirs[i])
console.log(`Directory ${this.createdDirs[i]} has been deleted.`)
}

console.log(`File ${absolutePath} has been deleted.`)
} else {
// Revert document.
const edit = new vscode.WorkspaceEdit()
Expand All @@ -369,7 +366,6 @@ export class DiffViewProvider {
// changes and saved during the edit.
await vscode.workspace.applyEdit(edit)
await updatedDocument.save()
console.log(`File ${absolutePath} has been reverted to its original content.`)

if (this.documentWasOpen) {
await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), {
Expand Down Expand Up @@ -398,7 +394,7 @@ export class DiffViewProvider {
vscode.window.tabGroups.close(tab).then(
() => undefined,
(err) => {
console.error(`Failed to close diff tab ${tab.label}`, err)
// Ignore errors when closing diff tabs - they may already be closed
},
),
)
Expand Down Expand Up @@ -432,31 +428,86 @@ export class DiffViewProvider {

// Open new diff editor.
return new Promise<vscode.TextEditor>((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

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) => {
if (timeoutId) clearTimeout(timeoutId)
disposableTabGroup.dispose()
resolve(editor)
},
(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(() => {
const found = checkAndResolve()
if (found) {
// Editor found and resolved, no need to continue listening
console.debug("Diff editor found via tab group change listener")
}
})

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(
() => {
// Give a brief moment for the editor to appear in tab groups
setTimeout(() => {
const found = checkAndResolve()
if (!found) {
// If not found immediately, rely on tab group change listener
// and the 10-second timeout fallback to handle resolution
console.debug(
"Diff editor not found in initial check, waiting for tab group changes...",
)
}
}, 100)
},
(err) => {
if (timeoutId) clearTimeout(timeoutId)
disposableTabGroup.dispose()
reject(new Error(`Failed to open diff editor command: ${err.message}`))
},
)

timeoutId = setTimeout(() => {
disposableTabGroup.dispose()
reject(new Error("Failed to open diff editor, please try again..."))
}, 10_000)
})()
})
}

Expand Down