From 4cad05521d54cec97179f49ca49404d97ae6a7ed Mon Sep 17 00:00:00 2001 From: Roo Code Date: Sat, 15 Nov 2025 17:31:17 +0000 Subject: [PATCH] fix: create new Position/Selection objects for scroll restoration - Replace direct selection assignment with new Position/Selection objects - Ensures proper transfer of cursor position between editor instances - Fixes issue where cursor would jump to start of file after closing diff view - Updated tests to properly mock Position and Selection constructors --- src/integrations/editor/DiffViewProvider.ts | 18 ++++++++++++++---- .../editor/__tests__/DiffViewProvider.spec.ts | 18 +++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 1d578240ab..264e51d60a 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -227,8 +227,13 @@ export class DiffViewProvider { await new Promise((resolve) => setTimeout(resolve, 50)) // Restore the cursor position and scroll position from the diff view - // First set the selection to where the cursor was - editor.selection = selection + // Create new Position/Selection objects instead of direct assignment to ensure proper transfer + if (selection) { + editor.selection = new vscode.Selection( + new vscode.Position(selection.anchor.line, selection.anchor.character), + new vscode.Position(selection.active.line, selection.active.character), + ) + } // Then reveal the range to ensure it's visible if (selection && !selection.isEmpty) { // If there's an actual selection, reveal it @@ -457,8 +462,13 @@ export class DiffViewProvider { await new Promise((resolve) => setTimeout(resolve, 50)) // Restore the cursor position and scroll position from the diff view - // First set the selection to where the cursor was - editor.selection = selection + // Create new Position/Selection objects instead of direct assignment to ensure proper transfer + if (selection) { + editor.selection = new vscode.Selection( + new vscode.Position(selection.anchor.line, selection.anchor.character), + new vscode.Position(selection.active.line, selection.active.character), + ) + } // Then reveal the range to ensure it's visible if (selection && !selection.isEmpty) { // If there's an actual selection, reveal it diff --git a/src/integrations/editor/__tests__/DiffViewProvider.spec.ts b/src/integrations/editor/__tests__/DiffViewProvider.spec.ts index 7f8a078b78..4fe67cf1eb 100644 --- a/src/integrations/editor/__tests__/DiffViewProvider.spec.ts +++ b/src/integrations/editor/__tests__/DiffViewProvider.spec.ts @@ -78,9 +78,21 @@ vi.mock("vscode", () => ({ Eight: 8, Nine: 9, }, - Range: vi.fn(), - Position: vi.fn(), - Selection: vi.fn(), + Range: vi.fn((startLine, startChar, endLine, endChar) => { + if (typeof startLine === "object" && typeof startChar === "object") { + return { start: startLine, end: startChar } + } + return { + start: { line: startLine, character: startChar }, + end: { line: endLine, character: endChar }, + } + }), + Position: vi.fn((line, character) => ({ line, character })), + Selection: vi.fn((anchor, active) => ({ + anchor, + active, + isEmpty: anchor.line === active.line && anchor.character === active.character, + })), TextEditorRevealType: { InCenter: 2 as any, InCenterIfOutsideViewport: 1 as any,