Skip to content
Closed
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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add a configuration option to enable/disable the auto-scroll behavior? Some users might prefer not to have their view automatically changed after saving edits.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it will be an issue. Reason being is that diff edits are not super common but when they do happen the user has already interrupted their workflow

}

// 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> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new methods need test coverage. The existing test file at src/integrations/editor/__tests__/EditorUtils.spec.ts doesn't include tests for openAndScrollToEdits() and extractFirstChangedLineFromDiff(). Could you add tests to ensure these methods work correctly with various diff formats and edge cases?

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add validation to ensure the extracted line number is within the document bounds? If a diff has an invalid line number (e.g., line 1000 in a 100-line file), this could cause issues when trying to scroll to it.

Suggested change
? new vscode.Selection(Math.max(firstChangedLine - 1, 0), 0, Math.max(firstChangedLine - 1, 0), 0)
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)
// Validate line number is within document bounds
const validLine = Math.min(Math.max(firstChangedLine - 1, 0), document.lineCount - 1)
// Show the document with selection at the first changed line
const selection = new vscode.Selection(validLine, 0, validLine, 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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the silent failure intentional here? Users won't know if the scroll operation fails. Would it be better to provide some user feedback, perhaps through a notification or status bar message?

}
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc could be more detailed about the expected diff format. Could you specify that this expects a unified diff format and what happens if no valid hunk headers are found?

* 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
}
}
Loading