@@ -99,8 +99,12 @@ export class DiffViewProvider {
9999 this . fadedOverlayController = new DecorationController ( "fadedOverlay" , this . activeDiffEditor )
100100 this . activeLineController = new DecorationController ( "activeLine" , this . activeDiffEditor )
101101 // Apply faded overlay to all lines initially.
102- this . fadedOverlayController . addLines ( 0 , this . activeDiffEditor . document . lineCount )
103- this . scrollEditorToLine ( 0 ) // Will this crash for new files?
102+ try {
103+ this . fadedOverlayController . addLines ( 0 , this . activeDiffEditor . document . lineCount )
104+ this . scrollEditorToLine ( 0 )
105+ } catch ( error ) {
106+ console . debug ( "DiffViewProvider: Failed to initialize decorations" , error )
107+ }
104108 this . streamedLines = [ ]
105109 }
106110
@@ -117,16 +121,28 @@ export class DiffViewProvider {
117121 }
118122
119123 const diffEditor = this . activeDiffEditor
120- const document = diffEditor ?. document
124+
125+ // Check if editor is still valid
126+ let document : vscode . TextDocument | undefined
127+ try {
128+ document = diffEditor ?. document
129+ } catch {
130+ throw new Error ( "Text editor is disposed, unable to edit file..." )
131+ }
121132
122133 if ( ! diffEditor || ! document ) {
123134 throw new Error ( "User closed text editor, unable to edit file..." )
124135 }
125136
126137 // Place cursor at the beginning of the diff editor to keep it out of
127138 // the way of the stream animation, but do this without stealing focus
128- const beginningOfDocument = new vscode . Position ( 0 , 0 )
129- diffEditor . selection = new vscode . Selection ( beginningOfDocument , beginningOfDocument )
139+ try {
140+ const beginningOfDocument = new vscode . Position ( 0 , 0 )
141+ diffEditor . selection = new vscode . Selection ( beginningOfDocument , beginningOfDocument )
142+ } catch ( error ) {
143+ // Editor might be disposed, continue with the update
144+ console . debug ( "DiffViewProvider: Failed to set selection" , error )
145+ }
130146
131147 const endLine = accumulatedLines . length
132148 // Replace all content up to the current line with accumulated lines.
@@ -176,12 +192,15 @@ export class DiffViewProvider {
176192 await vscode . workspace . applyEdit ( finalEdit )
177193
178194 // Clear all decorations at the end (after applying final edit).
179- this . fadedOverlayController . clear ( )
180- this . activeLineController . clear ( )
195+ this . fadedOverlayController ? .clear ( )
196+ this . activeLineController ? .clear ( )
181197 }
182198 }
183199
184- async saveChanges ( diagnosticsEnabled : boolean = true , writeDelayMs : number = DEFAULT_WRITE_DELAY_MS ) : Promise < {
200+ async saveChanges (
201+ diagnosticsEnabled : boolean = true ,
202+ writeDelayMs : number = DEFAULT_WRITE_DELAY_MS ,
203+ ) : Promise < {
185204 newProblemsMessage : string | undefined
186205 userEdits : string | undefined
187206 finalContent : string | undefined
@@ -216,22 +235,22 @@ export class DiffViewProvider {
216235 // and can address them accordingly. If problems don't change immediately after
217236 // applying a fix, won't be notified, which is generally fine since the
218237 // initial fix is usually correct and it may just take time for linters to catch up.
219-
238+
220239 let newProblemsMessage = ""
221-
240+
222241 if ( diagnosticsEnabled ) {
223242 // Add configurable delay to allow linters time to process and clean up issues
224243 // like unused imports (especially important for Go and other languages)
225244 // Ensure delay is non-negative
226245 const safeDelayMs = Math . max ( 0 , writeDelayMs )
227-
246+
228247 try {
229248 await delay ( safeDelayMs )
230249 } catch ( error ) {
231250 // Log error but continue - delay failure shouldn't break the save operation
232251 console . warn ( `Failed to apply write delay: ${ error } ` )
233252 }
234-
253+
235254 const postDiagnostics = vscode . languages . getDiagnostics ( )
236255
237256 const newProblems = await diagnosticsToProblemsString (
@@ -549,13 +568,19 @@ export class DiffViewProvider {
549568 }
550569
551570 private scrollEditorToLine ( line : number ) {
552- if ( this . activeDiffEditor ) {
553- const scrollLine = line + 4
571+ if ( ! this . activeDiffEditor ) {
572+ return
573+ }
554574
575+ try {
576+ const scrollLine = line + 4
555577 this . activeDiffEditor . revealRange (
556578 new vscode . Range ( scrollLine , 0 , scrollLine , 0 ) ,
557579 vscode . TextEditorRevealType . InCenter ,
558580 )
581+ } catch ( error ) {
582+ // Editor might be disposed
583+ console . debug ( "DiffViewProvider: Failed to scroll editor" , error )
559584 }
560585 }
561586
@@ -564,25 +589,30 @@ export class DiffViewProvider {
564589 return
565590 }
566591
567- const currentContent = this . activeDiffEditor . document . getText ( )
568- const diffs = diff . diffLines ( this . originalContent || "" , currentContent )
592+ try {
593+ const currentContent = this . activeDiffEditor . document . getText ( )
594+ const diffs = diff . diffLines ( this . originalContent || "" , currentContent )
569595
570- let lineCount = 0
596+ let lineCount = 0
571597
572- for ( const part of diffs ) {
573- if ( part . added || part . removed ) {
574- // Found the first diff, scroll to it without stealing focus.
575- this . activeDiffEditor . revealRange (
576- new vscode . Range ( lineCount , 0 , lineCount , 0 ) ,
577- vscode . TextEditorRevealType . InCenter ,
578- )
598+ for ( const part of diffs ) {
599+ if ( part . added || part . removed ) {
600+ // Found the first diff, scroll to it without stealing focus.
601+ this . activeDiffEditor . revealRange (
602+ new vscode . Range ( lineCount , 0 , lineCount , 0 ) ,
603+ vscode . TextEditorRevealType . InCenter ,
604+ )
579605
580- return
581- }
606+ return
607+ }
582608
583- if ( ! part . removed ) {
584- lineCount += part . count || 0
609+ if ( ! part . removed ) {
610+ lineCount += part . count || 0
611+ }
585612 }
613+ } catch ( error ) {
614+ // Editor might be disposed
615+ console . debug ( "DiffViewProvider: Failed to scroll to first diff" , error )
586616 }
587617 }
588618
@@ -599,15 +629,23 @@ export class DiffViewProvider {
599629 }
600630
601631 async reset ( ) : Promise < void > {
632+ // Dispose decoration controllers before clearing references
633+ if ( this . fadedOverlayController ) {
634+ this . fadedOverlayController . dispose ( )
635+ this . fadedOverlayController = undefined
636+ }
637+ if ( this . activeLineController ) {
638+ this . activeLineController . dispose ( )
639+ this . activeLineController = undefined
640+ }
641+
602642 await this . closeAllDiffViews ( )
603643 this . editType = undefined
604644 this . isEditing = false
605645 this . originalContent = undefined
606646 this . createdDirs = [ ]
607647 this . documentWasOpen = false
608648 this . activeDiffEditor = undefined
609- this . fadedOverlayController = undefined
610- this . activeLineController = undefined
611649 this . streamedLines = [ ]
612650 this . preDiagnostics = [ ]
613651 }
0 commit comments