diff --git a/src/integrations/editor/DiffViewProvider.ts b/src/integrations/editor/DiffViewProvider.ts index 5acf09ea78..89ff81bb6c 100644 --- a/src/integrations/editor/DiffViewProvider.ts +++ b/src/integrations/editor/DiffViewProvider.ts @@ -15,6 +15,7 @@ import { Task } from "../../core/task/Task" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" import { DecorationController } from "./DecorationController" +import { EditorUtils } from "./EditorUtils" export const DIFF_VIEW_URI_SCHEME = "cline-diff" export const DIFF_VIEW_LABEL_CHANGES = "Original ↔ Roo's Changes" @@ -319,6 +320,9 @@ export class DiffViewProvider { // Send the user feedback await task.say("user_feedback_diff", JSON.stringify(say)) + + // Open and focus the file, scrolling to the first edited section + await EditorUtils.openAndScrollToEdits(cwd, this.relPath, this.userEdits) } // Build XML response diff --git a/src/integrations/editor/EditorUtils.ts b/src/integrations/editor/EditorUtils.ts index eb7aa6c800..c23c4d0a10 100644 --- a/src/integrations/editor/EditorUtils.ts +++ b/src/integrations/editor/EditorUtils.ts @@ -207,4 +207,62 @@ export class EditorUtils { return null } } + + /** + * Opens a file and scrolls to the first edited section when user edits are detected + * @param cwd Current working directory + * @param relPath Relative path to the file + * @param userEdits The diff content showing user edits + */ + static async openAndScrollToEdits(cwd: string, relPath: string, userEdits: string): Promise { + try { + const absolutePath = path.resolve(cwd, relPath) + const fileUri = vscode.Uri.file(absolutePath) + + const firstChangedLine = this.extractFirstChangedLineFromDiff(userEdits) + if (!firstChangedLine) { + console.warn(`No changes found in user edits for ${relPath}`) + return + } + const document = await vscode.workspace.openTextDocument(fileUri) + + // Show the document with selection at the first changed line + const selection = + firstChangedLine !== null + ? new vscode.Selection(Math.max(firstChangedLine - 1, 0), 0, Math.max(firstChangedLine - 1, 0), 0) + : undefined + + await vscode.window.showTextDocument(document, { + preview: false, + selection, + viewColumn: vscode.ViewColumn.Active, + }) + } catch (error) { + console.warn(`Failed to open and scroll to edits for ${relPath}:`, error) + } + } + + /** + * Extracts the first line number where changes occur from a unified diff + * @param diffContent The unified diff content + * @returns The first line number where changes occur, or null if no changes found + */ + static extractFirstChangedLineFromDiff(diffContent: string): number | null { + if (!diffContent || diffContent.trim() === "") { + return null + } + + const lines = diffContent.split("\n") + + for (const line of lines) { + // Look for hunk headers like "@@ -1,4 +1,5 @@" + const hunkMatch = line.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/) + if (hunkMatch) { + // Return the line number from the new file (the + side) + return parseInt(hunkMatch[2], 10) + } + } + + return null + } }