From 25b1a0b2e78ffecb4f575dba94180295992fd096 Mon Sep 17 00:00:00 2001 From: seedlord Date: Tue, 22 Apr 2025 23:34:35 +0200 Subject: [PATCH 1/4] Fix: Preserve editor state and prevent tab unpinning during diffs - 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. --- evals/apps/cli/src/index.ts | 2 +- src/integrations/editor/DiffViewProvider.ts | 69 ++++++++++++++++++--- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/evals/apps/cli/src/index.ts b/evals/apps/cli/src/index.ts index 6b287042b08..c2213140766 100644 --- a/evals/apps/cli/src/index.ts +++ b/evals/apps/cli/src/index.ts @@ -190,7 +190,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server ROO_CODE_IPC_SOCKET_PATH: taskSocketPath, }, shell: "/bin/bash", - })`code --disable-workspace-trust -n ${workspacePath}` + })`code --disable-workspace-trust -W ${workspacePath}` // Give VSCode some time to spawn before connecting to its unix socket. await new Promise((resolve) => setTimeout(resolve, 3_000)) diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 0bf494854a4..e225230e0b8 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -17,6 +17,7 @@ export class DiffViewProvider { originalContent: string | undefined private createdDirs: string[] = [] private documentWasOpen = false + private originalViewColumn?: vscode.ViewColumn // Store the original view column private relPath?: string private newContent?: string private activeDiffEditor?: vscode.TextEditor @@ -65,11 +66,22 @@ export class DiffViewProvider { .filter( (tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath), ) + // Check if the document is already open and store its state + // DO NOT close the original tab to preserve pin status for (const tab of tabs) { - if (!tab.isDirty) { - await vscode.window.tabGroups.close(tab) + if (tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)) { + this.originalViewColumn = tab.group.viewColumn + this.documentWasOpen = true + // Ensure the tab is not dirty before proceeding, but don't close it + if (tab.isDirty) { + // Find the document associated with the tab and save it + const doc = vscode.workspace.textDocuments.find((d) => arePathsEqual(d.uri.fsPath, absolutePath)) + if (doc) { + await doc.save() + } + } + break // Found the relevant tab, no need to check others } - this.documentWasOpen = true } this.activeDiffEditor = await this.openDiffEditor() this.fadedOverlayController = new DecorationController("fadedOverlay", this.activeDiffEditor) @@ -156,9 +168,31 @@ export class DiffViewProvider { await updatedDocument.save() } - await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { preview: false }) + // Close the diff view first await this.closeAllDiffViews() + // If the original document was open, try to focus it. + // VS Code should handle showing the updated content automatically since the file was saved. + if (this.documentWasOpen && this.originalViewColumn) { + // Find the editor for the original document and reveal it + const originalEditor = vscode.window.visibleTextEditors.find( + (editor) => + arePathsEqual(editor.document.uri.fsPath, absolutePath) && + editor.viewColumn === this.originalViewColumn, + ) + if (originalEditor) { + // Reveal a range (e.g., the start) to ensure focus + const position = new vscode.Position(0, 0) + originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop) + } else { + // Fallback if editor not found (shouldn't happen often if documentWasOpen is true) + await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { + preview: false, + viewColumn: this.originalViewColumn, + }) + } + } + /* Getting diagnostics before and after the file edit is a better approach than automatically tracking problems in real-time. This method ensures we only @@ -237,12 +271,28 @@ export class DiffViewProvider { 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), { - preview: false, - }) - } + // Close the diff view first await this.closeAllDiffViews() + + // If the document was originally open, ensure it's focused. + // The revert logic already applied the original content and saved. + if (this.documentWasOpen && this.originalViewColumn) { + const originalEditor = vscode.window.visibleTextEditors.find( + (editor) => + arePathsEqual(editor.document.uri.fsPath, absolutePath) && + editor.viewColumn === this.originalViewColumn, + ) + if (originalEditor) { + const position = new vscode.Position(0, 0) + originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop) + } else { + // Fallback + await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { + preview: false, + viewColumn: this.originalViewColumn, + }) + } + } } // edit is done @@ -358,6 +408,7 @@ export class DiffViewProvider { this.originalContent = undefined this.createdDirs = [] this.documentWasOpen = false + this.originalViewColumn = undefined // Reset stored view column this.activeDiffEditor = undefined this.fadedOverlayController = undefined this.activeLineController = undefined From 67cd4c2ea51ce707e7845b75e14db6f9c6829a72 Mon Sep 17 00:00:00 2001 From: seedlord Date: Thu, 24 Apr 2025 01:59:50 +0200 Subject: [PATCH 2/4] Refactor: Extract focus logic in DiffViewProvider --- src/integrations/editor/DiffViewProvider.ts | 63 +++++++++------------ 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index e225230e0b8..ef6a34ed3da 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -173,25 +173,8 @@ export class DiffViewProvider { // If the original document was open, try to focus it. // VS Code should handle showing the updated content automatically since the file was saved. - if (this.documentWasOpen && this.originalViewColumn) { - // Find the editor for the original document and reveal it - const originalEditor = vscode.window.visibleTextEditors.find( - (editor) => - arePathsEqual(editor.document.uri.fsPath, absolutePath) && - editor.viewColumn === this.originalViewColumn, - ) - if (originalEditor) { - // Reveal a range (e.g., the start) to ensure focus - const position = new vscode.Position(0, 0) - originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop) - } else { - // Fallback if editor not found (shouldn't happen often if documentWasOpen is true) - await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { - preview: false, - viewColumn: this.originalViewColumn, - }) - } - } + // If the original document was open, try to focus it. + await this._focusOriginalDocument(absolutePath, this.originalViewColumn) /* Getting diagnostics before and after the file edit is a better approach than @@ -276,23 +259,8 @@ export class DiffViewProvider { // If the document was originally open, ensure it's focused. // The revert logic already applied the original content and saved. - if (this.documentWasOpen && this.originalViewColumn) { - const originalEditor = vscode.window.visibleTextEditors.find( - (editor) => - arePathsEqual(editor.document.uri.fsPath, absolutePath) && - editor.viewColumn === this.originalViewColumn, - ) - if (originalEditor) { - const position = new vscode.Position(0, 0) - originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop) - } else { - // Fallback - await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { - preview: false, - viewColumn: this.originalViewColumn, - }) - } - } + // If the document was originally open, ensure it's focused. + await this._focusOriginalDocument(absolutePath, this.originalViewColumn) } // edit is done @@ -401,6 +369,29 @@ export class DiffViewProvider { return result } + private async _focusOriginalDocument( + absolutePath: string, + viewColumn: vscode.ViewColumn | undefined, + ): Promise { + if (this.documentWasOpen && viewColumn) { + // Find the editor for the original document and reveal it + const originalEditor = vscode.window.visibleTextEditors.find( + (editor) => arePathsEqual(editor.document.uri.fsPath, absolutePath) && editor.viewColumn === viewColumn, + ) + if (originalEditor) { + // Reveal a range (e.g., the start) to ensure focus + const position = new vscode.Position(0, 0) + originalEditor.revealRange(new vscode.Range(position, position), vscode.TextEditorRevealType.AtTop) + } else { + // Fallback if editor not found + await vscode.window.showTextDocument(vscode.Uri.file(absolutePath), { + preview: false, + viewColumn: viewColumn, + }) + } + } + } + // close editor if open? async reset() { this.editType = undefined From 6e01e052963706dbc2eb85db7477577bc8a8ceb7 Mon Sep 17 00:00:00 2001 From: seedlord Date: Mon, 28 Apr 2025 23:13:20 +0200 Subject: [PATCH 3/4] Update index.ts --- evals/apps/cli/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evals/apps/cli/src/index.ts b/evals/apps/cli/src/index.ts index c2213140766..6b287042b08 100644 --- a/evals/apps/cli/src/index.ts +++ b/evals/apps/cli/src/index.ts @@ -190,7 +190,7 @@ const runExercise = async ({ run, task, server }: { run: Run; task: Task; server ROO_CODE_IPC_SOCKET_PATH: taskSocketPath, }, shell: "/bin/bash", - })`code --disable-workspace-trust -W ${workspacePath}` + })`code --disable-workspace-trust -n ${workspacePath}` // Give VSCode some time to spawn before connecting to its unix socket. await new Promise((resolve) => setTimeout(resolve, 3_000)) From b16d87ba6c9ca0e98e726cf4eef599a6d842df95 Mon Sep 17 00:00:00 2001 From: seedlord Date: Mon, 28 Apr 2025 23:23:21 +0200 Subject: [PATCH 4/4] Update DiffViewProvider.ts --- src/integrations/editor/DiffViewProvider.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index b765fae3174..7bde530e04f 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -17,6 +17,7 @@ export class DiffViewProvider { originalContent: string | undefined private createdDirs: string[] = [] private documentWasOpen = false + private originalViewColumn?: vscode.ViewColumn // Store the original view column private relPath?: string private newContent?: string private activeDiffEditor?: vscode.TextEditor @@ -65,11 +66,22 @@ export class DiffViewProvider { .filter( (tab) => tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath), ) + // Check if the document is already open and store its state + // DO NOT close the original tab to preserve pin status for (const tab of tabs) { - if (!tab.isDirty) { - await vscode.window.tabGroups.close(tab) + if (tab.input instanceof vscode.TabInputText && arePathsEqual(tab.input.uri.fsPath, absolutePath)) { + this.originalViewColumn = tab.group.viewColumn + this.documentWasOpen = true + // Ensure the tab is not dirty before proceeding, but don't close it + if (tab.isDirty) { + // Find the document associated with the tab and save it + const doc = vscode.workspace.textDocuments.find((d) => arePathsEqual(d.uri.fsPath, absolutePath)) + if (doc) { + await doc.save() + } + } + break // Found the relevant tab, no need to check others } - this.documentWasOpen = true } this.activeDiffEditor = await this.openDiffEditor() this.fadedOverlayController = new DecorationController("fadedOverlay", this.activeDiffEditor) @@ -385,6 +397,7 @@ export class DiffViewProvider { this.originalContent = undefined this.createdDirs = [] this.documentWasOpen = false + this.originalViewColumn = undefined // Reset stored view column this.activeDiffEditor = undefined this.fadedOverlayController = undefined this.activeLineController = undefined