Skip to content

Commit c2dd743

Browse files
authored
Fix: Preserve editor state and prevent tab unpinning during diffs (#2857)
- Maintains editor view column state when closing and reopening files during diff operations, ensuring tabs stay opened in their original position. - Prevents closing the original editor tab when opening the diff view, preserving pinned status when applying changes via write_to_file or apply_diff. - Updates VSCode workspace launch flag from -n to -W for compatibility.
1 parent 3d129e8 commit c2dd743

File tree

2 files changed

+61
-10
lines changed

2 files changed

+61
-10
lines changed

evals/apps/cli/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server
190190
ROO_CODE_IPC_SOCKET_PATH: taskSocketPath,
191191
},
192192
shell: "/bin/bash",
193-
})`code --disable-workspace-trust -n ${workspacePath}`
193+
})`code --disable-workspace-trust -W ${workspacePath}`
194194

195195
// Give VSCode some time to spawn before connecting to its unix socket.
196196
await new Promise((resolve) => setTimeout(resolve, 3_000))

src/integrations/editor/DiffViewProvider.ts

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class DiffViewProvider {
1717
originalContent: string | undefined
1818
private createdDirs: string[] = []
1919
private documentWasOpen = false
20+
private originalViewColumn?: vscode.ViewColumn // Store the original view column
2021
private relPath?: string
2122
private newContent?: string
2223
private activeDiffEditor?: vscode.TextEditor
@@ -65,11 +66,22 @@ export class DiffViewProvider {
6566
.filter(
6667
(tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath),
6768
)
69+
// Check if the document is already open and store its state
70+
// DO NOT close the original tab to preserve pin status
6871
for (const tab of tabs) {
69-
if (!tab.isDirty) {
70-
await vscode.window.tabGroups.close(tab)
72+
if (tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)) {
73+
this.originalViewColumn = tab.group.viewColumn
74+
this.documentWasOpen = true
75+
// Ensure the tab is not dirty before proceeding, but don't close it
76+
if (tab.isDirty) {
77+
// Find the document associated with the tab and save it
78+
const doc = vscode.workspace.textDocuments.find((d) => arePathsEqual(d.uri.fsPath, absolutePath))
79+
if (doc) {
80+
await doc.save()
81+
}
82+
}
83+
break // Found the relevant tab, no need to check others
7184
}
72-
this.documentWasOpen = true
7385
}
7486
this.activeDiffEditor = await this.openDiffEditor()
7587
this.fadedOverlayController = new DecorationController("fadedOverlay", this.activeDiffEditor)
@@ -156,9 +168,31 @@ export class DiffViewProvider {
156168
await updatedDocument.save()
157169
}
158170

159-
await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { preview: false })
171+
// Close the diff view first
160172
await this.closeAllDiffViews()
161173

174+
// If the original document was open, try to focus it.
175+
// VS Code should handle showing the updated content automatically since the file was saved.
176+
if (this.documentWasOpen && this.originalViewColumn) {
177+
// Find the editor for the original document and reveal it
178+
const originalEditor = vscode.window.visibleTextEditors.find(
179+
(editor) =>
180+
arePathsEqual(editor.document.uri.fsPath, absolutePath) &&
181+
editor.viewColumn === this.originalViewColumn,
182+
)
183+
if (originalEditor) {
184+
// Reveal a range (e.g., the start) to ensure focus
185+
const position = new vscode.Position(0, 0)
186+
originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop)
187+
} else {
188+
// Fallback if editor not found (shouldn't happen often if documentWasOpen is true)
189+
await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), {
190+
preview: false,
191+
viewColumn: this.originalViewColumn,
192+
})
193+
}
194+
}
195+
162196
/*
163197
Getting diagnostics before and after the file edit is a better approach than
164198
automatically tracking problems in real-time. This method ensures we only
@@ -237,12 +271,28 @@ export class DiffViewProvider {
237271
await vscode.workspace.applyEdit(edit)
238272
await updatedDocument.save()
239273
console.log(`File ${absolutePath} has been reverted to its original content.`)
240-
if (this.documentWasOpen) {
241-
await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), {
242-
preview: false,
243-
})
244-
}
274+
// Close the diff view first
245275
await this.closeAllDiffViews()
276+
277+
// If the document was originally open, ensure it's focused.
278+
// The revert logic already applied the original content and saved.
279+
if (this.documentWasOpen && this.originalViewColumn) {
280+
const originalEditor = vscode.window.visibleTextEditors.find(
281+
(editor) =>
282+
arePathsEqual(editor.document.uri.fsPath, absolutePath) &&
283+
editor.viewColumn === this.originalViewColumn,
284+
)
285+
if (originalEditor) {
286+
const position = new vscode.Position(0, 0)
287+
originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop)
288+
} else {
289+
// Fallback
290+
await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), {
291+
preview: false,
292+
viewColumn: this.originalViewColumn,
293+
})
294+
}
295+
}
246296
}
247297

248298
// edit is done
@@ -358,6 +408,7 @@ export class DiffViewProvider {
358408
this.originalContent = undefined
359409
this.createdDirs = []
360410
this.documentWasOpen = false
411+
this.originalViewColumn = undefined // Reset stored view column
361412
this.activeDiffEditor = undefined
362413
this.fadedOverlayController = undefined
363414
this.activeLineController = undefined

0 commit comments

Comments
 (0)