@@ -207,4 +207,62 @@ export class EditorUtils {
207207 return null
208208 }
209209 }
210+
211+ /**
212+ * Opens a file and scrolls to the first edited section when user edits are detected
213+ * @param cwd Current working directory
214+ * @param relPath Relative path to the file
215+ * @param userEdits The diff content showing user edits
216+ */
217+ static async openAndScrollToEdits ( cwd : string , relPath : string , userEdits : string ) : Promise < void > {
218+ try {
219+ const absolutePath = path . resolve ( cwd , relPath )
220+ const fileUri = vscode . Uri . file ( absolutePath )
221+
222+ // Extract the first changed line number from the diff
223+ const firstChangedLine = this . extractFirstChangedLineFromDiff ( userEdits )
224+
225+ // Open the document
226+ const document = await vscode . workspace . openTextDocument ( fileUri )
227+
228+ // Show the document with selection at the first changed line
229+ const selection =
230+ firstChangedLine !== null
231+ ? new vscode . Selection ( Math . max ( firstChangedLine - 1 , 0 ) , 0 , Math . max ( firstChangedLine - 1 , 0 ) , 0 )
232+ : undefined
233+
234+ await vscode . window . showTextDocument ( document , {
235+ preview : false ,
236+ selection,
237+ viewColumn : vscode . ViewColumn . Active ,
238+ } )
239+ } catch ( error ) {
240+ // Log error but don't throw - this is a nice-to-have feature
241+ console . warn ( `Failed to open and scroll to edits for ${ relPath } :` , error )
242+ }
243+ }
244+
245+ /**
246+ * Extracts the first line number where changes occur from a unified diff
247+ * @param diffContent The unified diff content
248+ * @returns The first line number where changes occur, or null if no changes found
249+ */
250+ static extractFirstChangedLineFromDiff ( diffContent : string ) : number | null {
251+ if ( ! diffContent || diffContent . trim ( ) === "" ) {
252+ return null
253+ }
254+
255+ const lines = diffContent . split ( "\n" )
256+
257+ for ( const line of lines ) {
258+ // Look for hunk headers like "@@ -1,4 +1,5 @@"
259+ const hunkMatch = line . match ( / ^ @ @ \s + - ( \d + ) (?: , \d + ) ? \s + \+ ( \d + ) (?: , \d + ) ? \s + @ @ / )
260+ if ( hunkMatch ) {
261+ // Return the line number from the new file (the + side)
262+ return parseInt ( hunkMatch [ 2 ] , 10 )
263+ }
264+ }
265+
266+ return null
267+ }
210268}
0 commit comments