@@ -528,6 +528,7 @@ export class DiffViewProvider {
528528 /**
529529 * Formats a standardized XML response for file write operations
530530 *
531+ * @param task The current task context for sending user feedback
531532 * @param cwd Current working directory for path resolution
532533 * @param isNewFile Whether this is a new file or an existing file being modified
533534 * @returns Formatted message and say object for UI feedback
@@ -670,6 +671,25 @@ export class DiffViewProvider {
670671 let timeoutId : NodeJS . Timeout | undefined
671672 const disposables : vscode . Disposable [ ] = [ ]
672673
674+ const cleanup = ( ) => {
675+ if ( timeoutId ) {
676+ clearTimeout ( timeoutId )
677+ timeoutId = undefined
678+ }
679+ disposables . forEach ( ( d ) => d . dispose ( ) )
680+ disposables . length = 0
681+ }
682+
683+ // Set timeout for the entire operation
684+ timeoutId = setTimeout ( ( ) => {
685+ cleanup ( )
686+ reject (
687+ new Error (
688+ `Failed to open diff editor for ${ rightUri . fsPath } within ${ DIFF_EDITOR_TIMEOUT / 1000 } seconds. The editor may be blocked or VS Code may be unresponsive.` ,
689+ ) ,
690+ )
691+ } , DIFF_EDITOR_TIMEOUT )
692+
673693 const leftUri = vscode . Uri . parse ( `${ DIFF_VIEW_URI_SCHEME } :${ fileName } ` ) . with ( {
674694 query : Buffer . from ( this . originalContent ?? "" ) . toString ( "base64" ) ,
675695 } )
@@ -683,58 +703,94 @@ export class DiffViewProvider {
683703 this . suppressInteractionFlag = true
684704 // Implement improved diff view placement logic
685705 const previousEditor = vscode . window . activeTextEditor
706+
686707 this . prepareDiffViewPlacement ( rightUri . fsPath ) . then ( ( ) => {
687- vscode . commands
688- . executeCommand ( "vscode.diff" , leftUri , rightUri , title , textDocumentShowOptions )
689- . then ( async ( ) => {
690- // set interaction flag to false to allow autoFocus to be triggered
691- this . suppressInteractionFlag = false
692-
693- // Get the active text editor, which should be the diff editor opened by vscode.diff
694- const diffEditor = vscode . window . activeTextEditor
695-
696- // Ensure we have a valid editor and it's the one we expect (the right side of the diff)
697- if ( ! diffEditor || ! arePathsEqual ( diffEditor . document . uri . fsPath , rightUri . fsPath ) ) {
698- reject ( new Error ( "Failed to get diff editor after opening." ) )
699- return
700- }
701-
702- this . activeDiffEditor = diffEditor // Assign to activeDiffEditor
703-
704- // Ensure rightUri is tracked even if not explicitly shown again
705- this . rooOpenedTabs . add ( rightUri . toString ( ) )
706-
707- // If autoFocus is disabled, explicitly clear the selection to prevent cursor focus.
708- if ( ! settings . autoFocus ) {
709- // Use dynamically read autoFocus
710- // Add a small delay to allow VS Code to potentially set focus first,
711- // then clear it.
712- await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) )
713- const beginningOfDocument = new vscode . Position ( 0 , 0 )
714- diffEditor . selection = new vscode . Selection ( beginningOfDocument , beginningOfDocument )
715- }
716-
717- // if this happens in a window different from the active one, we need to show the document
718- if ( previousEditor ) {
719- await this . showTextDocumentSafe ( {
720- textDocument : previousEditor . document ,
721- options : {
722- preview : false ,
723- preserveFocus : false ,
724- selection : previousEditor . selection ,
725- viewColumn : previousEditor . viewColumn ,
708+ this . showTextDocumentSafe ( {
709+ uri : rightUri ,
710+ options : {
711+ ...textDocumentShowOptions ,
712+ viewColumn : this . viewColumn , // Ensure we use the correct view column
713+ } ,
714+ } ) . then (
715+ ( ) => {
716+ vscode . commands
717+ . executeCommand ( "vscode.diff" , leftUri , rightUri , title , textDocumentShowOptions )
718+ . then (
719+ async ( ) => {
720+ // set interaction flag to false to allow autoFocus to be triggered
721+ this . suppressInteractionFlag = false
722+
723+ // Get the active text editor, which should be the diff editor opened by vscode.diff
724+ const diffEditor = vscode . window . activeTextEditor
725+
726+ // Ensure we have a valid editor and it's the one we expect (the right side of the diff)
727+ if (
728+ ! diffEditor ||
729+ ! arePathsEqual ( diffEditor . document . uri . fsPath , rightUri . fsPath )
730+ ) {
731+ cleanup ( )
732+ reject (
733+ new Error (
734+ `Failed to execute diff command for ${ rightUri . fsPath } : No active editor found.` ,
735+ ) ,
736+ )
737+ return
738+ }
739+
740+ this . activeDiffEditor = diffEditor // Assign to activeDiffEditor
741+
742+ // Ensure rightUri is tracked even if not explicitly shown again
743+ this . rooOpenedTabs . add ( rightUri . toString ( ) )
744+
745+ // If autoFocus is disabled, explicitly clear the selection to prevent cursor focus.
746+ if ( ! settings . autoFocus ) {
747+ // Use dynamically read autoFocus
748+ // Add a small delay to allow VS Code to potentially set focus first,
749+ // then clear it.
750+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) )
751+ const beginningOfDocument = new vscode . Position ( 0 , 0 )
752+ diffEditor . selection = new vscode . Selection (
753+ beginningOfDocument ,
754+ beginningOfDocument ,
755+ )
756+ }
757+
758+ // if this happens in a window different from the active one, we need to show the document
759+ if ( previousEditor ) {
760+ await this . showTextDocumentSafe ( {
761+ textDocument : previousEditor . document ,
762+ options : {
763+ preview : false ,
764+ preserveFocus : false ,
765+ selection : previousEditor . selection ,
766+ viewColumn : previousEditor . viewColumn ,
767+ } ,
768+ } )
769+ }
770+
771+ cleanup ( )
772+ resolve ( diffEditor )
773+ } ,
774+ ( err ) => {
775+ cleanup ( )
776+ reject (
777+ new Error (
778+ `Failed to execute diff command for ${ rightUri . fsPath } : ${ err . message } ` ,
779+ ) ,
780+ )
726781 } ,
727- } )
728- }
729-
730- // Resolve the promise with the diff editor
731- resolve ( diffEditor )
732- } )
733- // Removed the second .then block that called getEditorFromDiffTab
734- // This may happen on very slow machines ie project idx
735- setTimeout ( ( ) => {
782+ )
783+ } ,
784+ ( err ) => {
785+ cleanup ( )
786+ reject ( new Error ( `Failed to execute diff command for ${ rightUri . fsPath } : ${ err . message } ` ) )
787+ } ,
788+ )
789+
790+ timeoutId = setTimeout ( ( ) => {
791+ cleanup ( )
736792 reject ( new Error ( "Failed to open diff editor, please try again..." ) )
737- } , 10_000 )
793+ } , DIFF_EDITOR_TIMEOUT )
738794 } )
739795 } )
740796 }
0 commit comments