4
4
*--------------------------------------------------------------------------------------------*/
5
5
6
6
import { Disposable } from '../../../../../../base/common/lifecycle.js' ;
7
- import { autorunWithStore , derived , IObservable } from '../../../../../../base/common/observable.js' ;
7
+ import { autorunWithStore , derived , IObservable , observableFromEvent } from '../../../../../../base/common/observable.js' ;
8
8
import { ICodeEditor } from '../../../../../browser/editorBrowser.js' ;
9
9
import { observableCodeEditor } from '../../../../../browser/observableCodeEditor.js' ;
10
10
import { rangeIsSingleLine } from '../../../../../browser/widget/diffEditor/components/diffEditorViewZones/diffEditorViewZones.js' ;
11
+ import { LineSource , renderLines , RenderOptions } from '../../../../../browser/widget/diffEditor/components/diffEditorViewZones/renderLines.js' ;
11
12
import { diffLineDeleteDecorationBackgroundWithIndicator , diffLineDeleteDecorationBackground , diffLineAddDecorationBackgroundWithIndicator , diffLineAddDecorationBackground , diffWholeLineAddDecoration , diffAddDecorationEmpty , diffAddDecoration } from '../../../../../browser/widget/diffEditor/registrations.contribution.js' ;
13
+ import { applyViewZones , IObservableViewZone } from '../../../../../browser/widget/diffEditor/utils.js' ;
14
+ import { EditorOption } from '../../../../../common/config/editorOptions.js' ;
12
15
import { Range } from '../../../../../common/core/range.js' ;
13
16
import { AbstractText } from '../../../../../common/core/textEdit.js' ;
14
17
import { DetailedLineRangeMapping } from '../../../../../common/diff/rangeMapping.js' ;
15
- import { IModelDeltaDecoration } from '../../../../../common/model.js' ;
18
+ import { IModelDeltaDecoration , ITextModel } from '../../../../../common/model.js' ;
16
19
import { ModelDecorationOptions } from '../../../../../common/model/textModel.js' ;
17
- import { classNames } from './inlineEditsView.js' ;
20
+ import { InlineDecoration , InlineDecorationType } from '../../../../../common/viewModel.js' ;
21
+ import { classNames } from './utils.js' ;
18
22
19
23
export interface IOriginalEditorInlineDiffViewState {
20
24
diff : DetailedLineRangeMapping [ ] ;
21
25
modifiedText : AbstractText ;
22
- showInline : boolean ;
26
+ mode : 'mixedLines' | 'interleavedLines' | 'sideBySide' ;
27
+
23
28
modifiedCodeEditor : ICodeEditor ;
24
29
}
25
30
@@ -31,6 +36,7 @@ export class OriginalEditorInlineDiffView extends Disposable {
31
36
constructor (
32
37
private readonly _originalEditor : ICodeEditor ,
33
38
private readonly _state : IObservable < IOriginalEditorInlineDiffViewState | undefined > ,
39
+ private readonly _modifiedTextModel : ITextModel ,
34
40
) {
35
41
super ( ) ;
36
42
@@ -43,14 +49,69 @@ export class OriginalEditorInlineDiffView extends Disposable {
43
49
store . add ( observableCodeEditor ( e ) . setDecorations ( this . _decorations . map ( d => d ?. modifiedDecorations ?? [ ] ) ) ) ;
44
50
}
45
51
} ) ) ;
52
+
53
+ const editor = observableCodeEditor ( this . _originalEditor ) ;
54
+
55
+ const tokenizationFinished = modelTokenizationFinished ( _modifiedTextModel ) ;
56
+
57
+ const originalViewZones = derived ( this , ( reader ) => {
58
+ const originalModel = editor . model . read ( reader ) ;
59
+ if ( ! originalModel ) { return [ ] ; }
60
+
61
+ const origViewZones : IObservableViewZone [ ] = [ ] ;
62
+ const renderOptions = RenderOptions . fromEditor ( this . _originalEditor ) ;
63
+ const modLineHeight = editor . getOption ( EditorOption . lineHeight ) . read ( reader ) ;
64
+
65
+ const s = this . _state . read ( reader ) ;
66
+ if ( ! s ) { return origViewZones ; }
67
+
68
+ for ( const diff of s . diff ) {
69
+ if ( s . mode !== 'interleavedLines' ) {
70
+ continue ;
71
+ }
72
+
73
+ tokenizationFinished . read ( reader ) ; // Update view-zones once tokenization completes
74
+
75
+ const source = new LineSource ( diff . modified . mapToLineArray ( l => this . _modifiedTextModel . tokenization . getLineTokens ( l ) ) ) ;
76
+
77
+ const decorations : InlineDecoration [ ] = [ ] ;
78
+ for ( const i of diff . innerChanges || [ ] ) {
79
+ decorations . push ( new InlineDecoration (
80
+ i . modifiedRange . delta ( - ( diff . original . startLineNumber - 1 ) ) ,
81
+ diffAddDecoration . className ! ,
82
+ InlineDecorationType . Regular ,
83
+ ) ) ;
84
+ }
85
+
86
+ const deletedCodeDomNode = document . createElement ( 'div' ) ;
87
+ deletedCodeDomNode . classList . add ( 'view-lines' , 'line-insert' , 'monaco-mouse-cursor-text' ) ;
88
+ // .inline-deleted-margin-view-zone
89
+
90
+ const result = renderLines ( source , renderOptions , decorations , deletedCodeDomNode ) ;
91
+
92
+ origViewZones . push ( {
93
+ afterLineNumber : diff . original . endLineNumberExclusive - 1 ,
94
+ domNode : deletedCodeDomNode ,
95
+ heightInPx : result . heightInLines * modLineHeight ,
96
+ minWidthInPx : result . minWidthInPx ,
97
+
98
+ showInHiddenAreas : true ,
99
+ suppressMouseDown : true ,
100
+ } ) ;
101
+ }
102
+
103
+ return origViewZones ;
104
+ } ) ;
105
+
106
+ this . _register ( applyViewZones ( this . _originalEditor , originalViewZones ) ) ;
46
107
}
47
108
48
109
private readonly _decorations = derived ( this , reader => {
49
110
const diff = this . _state . read ( reader ) ;
50
111
if ( ! diff ) { return undefined ; }
51
112
52
113
const modified = diff . modifiedText ;
53
- const showInline = diff . showInline ;
114
+ const showInline = diff . mode === 'mixedLines' ;
54
115
55
116
const renderIndicators = false ;
56
117
const showEmptyDecorations = true ;
@@ -59,7 +120,7 @@ export class OriginalEditorInlineDiffView extends Disposable {
59
120
const modifiedDecorations : IModelDeltaDecoration [ ] = [ ] ;
60
121
61
122
for ( const m of diff . diff ) {
62
- const showFullLineDecorations = false ;
123
+ const showFullLineDecorations = true ;
63
124
if ( showFullLineDecorations ) {
64
125
if ( ! m . original . isEmpty ) {
65
126
originalDecorations . push ( { range : m . original . toInclusiveRange ( ) ! , options : renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground } ) ;
@@ -133,3 +194,8 @@ function allowsTrueInlineDiffRendering(mapping: DetailedLineRangeMapping): boole
133
194
return mapping . innerChanges . every ( c =>
134
195
( rangeIsSingleLine ( c . modifiedRange ) && rangeIsSingleLine ( c . originalRange ) ) ) ;
135
196
}
197
+
198
+ let i = 0 ;
199
+ function modelTokenizationFinished ( model : ITextModel ) : IObservable < number > {
200
+ return observableFromEvent ( model . onDidChangeTokens , ( ) => i ++ ) ;
201
+ }
0 commit comments