6
6
import './media/chatEditorController.css' ;
7
7
import { addStandardDisposableListener , getTotalWidth } from '../../../../base/browser/dom.js' ;
8
8
import { Disposable , DisposableStore , dispose , toDisposable } from '../../../../base/common/lifecycle.js' ;
9
- import { autorun , autorunWithStore , derived , IObservable , observableFromEvent , observableValue , transaction } from '../../../../base/common/observable.js' ;
9
+ import { autorun , autorunWithStore , derived , IObservable , observableFromEvent , observableValue } from '../../../../base/common/observable.js' ;
10
10
import { themeColorFromId } from '../../../../base/common/themables.js' ;
11
11
import { ICodeEditor , IOverlayWidget , IOverlayWidgetPosition , IOverlayWidgetPositionCoordinates , IViewZone , MouseTargetType } from '../../../../editor/browser/editorBrowser.js' ;
12
12
import { LineSource , renderLines , RenderOptions } from '../../../../editor/browser/widget/diffEditor/components/diffEditorViewZones/renderLines.js' ;
@@ -80,9 +80,10 @@ export class ChatEditorController extends Disposable implements IEditorContribut
80
80
this . _ctxHasEditorModification = ctxHasEditorModification . bindTo ( contextKeyService ) ;
81
81
this . _ctxRequestInProgress = ctxHasRequestInProgress . bindTo ( contextKeyService ) ;
82
82
83
- const fontInfoObs = observableCodeEditor ( this . _editor ) . getOption ( EditorOption . fontInfo ) ;
84
- const lineHeightObs = observableCodeEditor ( this . _editor ) . getOption ( EditorOption . lineHeight ) ;
85
- const modelObs = observableCodeEditor ( this . _editor ) . model ;
83
+ const editorObs = observableCodeEditor ( this . _editor ) ;
84
+ const fontInfoObs = editorObs . getOption ( EditorOption . fontInfo ) ;
85
+ const lineHeightObs = editorObs . getOption ( EditorOption . lineHeight ) ;
86
+ const modelObs = editorObs . model ;
86
87
87
88
88
89
this . _store . add ( autorun ( r => {
@@ -112,13 +113,13 @@ export class ChatEditorController extends Disposable implements IEditorContribut
112
113
const currentEditorEntry = entryForEditor . read ( r ) ;
113
114
114
115
if ( ! currentEditorEntry ) {
115
- this . _clearRendering ( ) ;
116
+ this . _clear ( ) ;
116
117
didReval = false ;
117
118
return ;
118
119
}
119
120
120
121
if ( this . _editor . getOption ( EditorOption . inDiffEditor ) && ! _instantiationService . invokeFunction ( isDiffEditorForEntry , currentEditorEntry . entry , this . _editor ) ) {
121
- this . _clearRendering ( ) ;
122
+ this . _clear ( ) ;
122
123
return ;
123
124
}
124
125
@@ -145,7 +146,16 @@ export class ChatEditorController extends Disposable implements IEditorContribut
145
146
lineHeightObs . read ( r ) ;
146
147
147
148
const diff = entry ?. diffInfo . read ( r ) ;
148
- this . _updateWithDiff ( entry , diff ) ;
149
+
150
+ // Add line decorations (just markers, no UI) for diff navigation
151
+ this . _updateDiffLineDecorations ( diff ) ;
152
+
153
+ // Add diff decoration to the UI (unless in diff editor)
154
+ if ( ! this . _editor . getOption ( EditorOption . inDiffEditor ) ) {
155
+ this . _updateDiffRendering ( entry , diff ) ;
156
+ } else {
157
+ this . _clearDiffRendering ( ) ;
158
+ }
149
159
150
160
if ( ! didReval && ! diff . identical ) {
151
161
didReval = true ;
@@ -199,11 +209,19 @@ export class ChatEditorController extends Disposable implements IEditorContribut
199
209
}
200
210
201
211
override dispose ( ) : void {
202
- this . _clearRendering ( ) ;
212
+ this . _clear ( ) ;
203
213
super . dispose ( ) ;
204
214
}
205
215
206
- private _clearRendering ( ) {
216
+ private _clear ( ) {
217
+ this . _clearDiffRendering ( ) ;
218
+ this . _diffLineDecorations . clear ( ) ;
219
+ this . _currentChangeIndex . set ( undefined , undefined ) ;
220
+ this . _currentEntryIndex . set ( undefined , undefined ) ;
221
+ this . _ctxHasEditorModification . reset ( ) ;
222
+ }
223
+
224
+ private _clearDiffRendering ( ) {
207
225
this . _editor . changeViewZones ( ( viewZoneChangeAccessor ) => {
208
226
for ( const id of this . _viewZones ) {
209
227
viewZoneChangeAccessor . removeZone ( id ) ;
@@ -212,18 +230,11 @@ export class ChatEditorController extends Disposable implements IEditorContribut
212
230
this . _viewZones = [ ] ;
213
231
this . _diffHunksRenderStore . clear ( ) ;
214
232
this . _diffVisualDecorations . clear ( ) ;
215
- this . _diffLineDecorations . clear ( ) ;
216
- this . _ctxHasEditorModification . reset ( ) ;
217
- transaction ( tx => {
218
- this . _currentEntryIndex . set ( undefined , tx ) ;
219
- this . _currentChangeIndex . set ( undefined , tx ) ;
220
- } ) ;
221
233
this . _scrollLock = false ;
222
234
}
223
235
224
- private _updateWithDiff ( entry : IModifiedFileEntry , diff : IDocumentDiff ) : void {
236
+ private _updateDiffRendering ( entry : IModifiedFileEntry , diff : IDocumentDiff ) : void {
225
237
226
- this . _ctxHasEditorModification . set ( ! diff . identical ) ;
227
238
const originalModel = entry . originalModel ;
228
239
229
240
const chatDiffAddDecoration = ModelDecorationOptions . createDynamic ( {
@@ -255,7 +266,6 @@ export class ChatEditorController extends Disposable implements IEditorContribut
255
266
}
256
267
this . _viewZones = [ ] ;
257
268
const modifiedVisualDecorations : IModelDeltaDecoration [ ] = [ ] ;
258
- const modifiedLineDecorations : IModelDeltaDecoration [ ] = [ ] ;
259
269
const mightContainNonBasicASCII = originalModel . mightContainNonBasicASCII ( ) ;
260
270
const mightContainRTL = originalModel . mightContainRTL ( ) ;
261
271
const renderOptions = RenderOptions . fromEditor ( this . _editor ) ;
@@ -344,16 +354,9 @@ export class ChatEditorController extends Disposable implements IEditorContribut
344
354
stickiness : TrackedRangeStickiness . AlwaysGrowsWhenTypingAtEdges
345
355
}
346
356
} ) ;
347
-
348
- // Add line decorations for diff navigation
349
- modifiedLineDecorations . push ( {
350
- range : diffEntry . modified . toInclusiveRange ( ) ?? new Range ( diffEntry . modified . startLineNumber , 1 , diffEntry . modified . startLineNumber , Number . MAX_SAFE_INTEGER ) ,
351
- options : ChatEditorController . _diffLineDecorationData
352
- } ) ;
353
357
}
354
358
355
359
this . _diffVisualDecorations . set ( modifiedVisualDecorations ) ;
356
- this . _diffLineDecorations . set ( modifiedLineDecorations ) ;
357
360
} ) ;
358
361
359
362
const diffHunkDecoCollection = this . _editor . createDecorationsCollection ( diffHunkDecorations ) ;
@@ -428,6 +431,20 @@ export class ChatEditorController extends Disposable implements IEditorContribut
428
431
} ) ) ;
429
432
}
430
433
434
+ private _updateDiffLineDecorations ( diff : IDocumentDiff ) : void {
435
+ this . _ctxHasEditorModification . set ( ! diff . identical ) ;
436
+
437
+ const modifiedLineDecorations : IModelDeltaDecoration [ ] = [ ] ;
438
+
439
+ for ( const diffEntry of diff . changes ) {
440
+ modifiedLineDecorations . push ( {
441
+ range : diffEntry . modified . toInclusiveRange ( ) ?? new Range ( diffEntry . modified . startLineNumber , 1 , diffEntry . modified . startLineNumber , Number . MAX_SAFE_INTEGER ) ,
442
+ options : ChatEditorController . _diffLineDecorationData
443
+ } ) ;
444
+ }
445
+ this . _diffLineDecorations . set ( modifiedLineDecorations ) ;
446
+ }
447
+
431
448
unlockScroll ( ) : void {
432
449
this . _scrollLock = false ;
433
450
}
@@ -533,6 +550,12 @@ export class ChatEditorController extends Disposable implements IEditorContribut
533
550
if ( ! this . _editor . hasModel ( ) ) {
534
551
return ;
535
552
}
553
+
554
+ const entry = this . _chatEditingService . currentEditingSessionObs . get ( ) ?. getEntry ( this . _editor . getModel ( ) . uri ) ;
555
+ if ( ! entry ) {
556
+ return ;
557
+ }
558
+
536
559
const lineRelativeTop = this . _editor . getTopForLineNumber ( this . _editor . getPosition ( ) . lineNumber ) - this . _editor . getScrollTop ( ) ;
537
560
let closestDistance = Number . MAX_VALUE ;
538
561
@@ -549,33 +572,30 @@ export class ChatEditorController extends Disposable implements IEditorContribut
549
572
}
550
573
}
551
574
552
- if ( ! ( widget instanceof DiffHunkWidget ) ) {
553
- return ;
554
- }
555
-
556
-
557
- const lineNumber = widget . getStartLineNumber ( ) ;
558
- const position = lineNumber ? new Position ( lineNumber , 1 ) : undefined ;
559
575
let selection = this . _editor . getSelection ( ) ;
560
- if ( position && ! selection . containsPosition ( position ) ) {
561
- selection = Selection . fromPositions ( position ) ;
576
+ if ( widget instanceof DiffHunkWidget ) {
577
+ const lineNumber = widget . getStartLineNumber ( ) ;
578
+ const position = lineNumber ? new Position ( lineNumber , 1 ) : undefined ;
579
+ if ( position && ! selection . containsPosition ( position ) ) {
580
+ selection = Selection . fromPositions ( position ) ;
581
+ }
562
582
}
563
583
564
584
const isDiffEditor = this . _editor . getOption ( EditorOption . inDiffEditor ) ;
565
585
566
586
if ( isDiffEditor ) {
567
587
// normal EDITOR
568
- await this . _editorService . openEditor ( { resource : widget . entry . modifiedURI } ) ;
588
+ await this . _editorService . openEditor ( { resource : entry . modifiedURI } ) ;
569
589
570
590
} else {
571
591
// DIFF editor
572
592
const defaultAgentName = this . _chatAgentService . getDefaultAgent ( ChatAgentLocation . EditingSession ) ?. fullName ;
573
593
const diffEditor = await this . _editorService . openEditor ( {
574
- original : { resource : widget . entry . originalURI , options : { selection : undefined } } ,
575
- modified : { resource : widget . entry . modifiedURI , options : { selection } } ,
594
+ original : { resource : entry . originalURI , options : { selection : undefined } } ,
595
+ modified : { resource : entry . modifiedURI , options : { selection } } ,
576
596
label : defaultAgentName
577
- ? localize ( 'diff.agent' , '{0} (changes from {1})' , basename ( widget . entry . modifiedURI ) , defaultAgentName )
578
- : localize ( 'diff.generic' , '{0} (changes from chat)' , basename ( widget . entry . modifiedURI ) )
597
+ ? localize ( 'diff.agent' , '{0} (changes from {1})' , basename ( entry . modifiedURI ) , defaultAgentName )
598
+ : localize ( 'diff.generic' , '{0} (changes from chat)' , basename ( entry . modifiedURI ) )
579
599
} ) ;
580
600
581
601
if ( diffEditor && diffEditor . input ) {
@@ -586,7 +606,7 @@ export class ChatEditorController extends Disposable implements IEditorContribut
586
606
587
607
// close diff editor when entry is decided
588
608
const d = autorun ( r => {
589
- const state = widget . entry . state . read ( r ) ;
609
+ const state = entry . state . read ( r ) ;
590
610
if ( state === WorkingSetEntryState . Accepted || state === WorkingSetEntryState . Rejected ) {
591
611
d . dispose ( ) ;
592
612
this . _editorService . closeEditor ( editorIdent ) ;
0 commit comments