Skip to content
Open
Show file tree
Hide file tree
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
4 changes: 4 additions & 0 deletions src/integrations/editor/DiffViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
58 changes: 58 additions & 0 deletions src/integrations/editor/EditorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
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
}
}