6
6
import java .util .Collections ;
7
7
import java .util .List ;
8
8
import java .util .concurrent .CompletableFuture ;
9
+ import java .util .concurrent .atomic .AtomicInteger ;
9
10
10
- import org .eclipse .jface .text .ITextListener ;
11
+ import org .eclipse .jface .text .BadLocationException ;
12
+ import org .eclipse .jface .text .IDocument ;
13
+ import org .eclipse .jface .text .IRegion ;
11
14
import org .eclipse .jface .text .ITextViewer ;
12
- import org .eclipse .jface .text .TextEvent ;
13
15
import org .eclipse .jface .text .provisional .codelens .internal .CodeLens ;
14
16
import org .eclipse .jface .text .provisional .codelens .internal .CodeLensData ;
15
17
import org .eclipse .jface .text .provisional .codelens .internal .CodeLensHelper ;
16
18
import org .eclipse .jface .text .provisional .viewzones .ViewZoneChangeAccessor ;
19
+ import org .eclipse .jface .text .reconciler .DirtyRegion ;
20
+ import org .eclipse .jface .text .reconciler .IReconcilingStrategy ;
21
+ import org .eclipse .swt .custom .StyledText ;
22
+ import org .eclipse .swt .custom .patch .StyledTextPatcher ;
17
23
import org .eclipse .swt .widgets .Display ;
18
24
19
25
// /vscode/src/vs/editor/contrib/codelens/common/codelens.ts
20
- public class CodeLensContribution {
26
+ public class CodeLensStrategy implements IReconcilingStrategy {
21
27
22
28
private final ITextViewer textViewer ;
23
29
private final List <String > targets ;
24
- private ITextListener internalListener = new ITextListener () {
25
30
26
- @ Override
27
- public void textChanged (TextEvent event ) {
28
- if (event .getDocumentEvent () != null ) {
29
- onModelChange ();
30
- }
31
- }
32
- };
31
+ private AtomicInteger count = new AtomicInteger (0 );
33
32
34
33
private ViewZoneChangeAccessor accessor ;
35
34
private List <CodeLens > _lenses ;
36
- private CompletableFuture <Collection <CodeLensData >> symbolsPromise ;
35
+ private CompletableFuture <Void > symbolsPromise ;
36
+ private boolean invalidateTextPresentation ;
37
+
38
+ public CodeLensStrategy (ITextViewer textViewer ) {
39
+ this (textViewer , true );
40
+ }
37
41
38
- public CodeLensContribution (ITextViewer textViewer ) {
42
+ public CodeLensStrategy (ITextViewer textViewer , boolean invalidateTextPresentation ) {
39
43
this .textViewer = textViewer ;
44
+ this .invalidateTextPresentation = invalidateTextPresentation ;
40
45
this .targets = new ArrayList <>();
41
- textViewer .addTextListener (internalListener );
42
- try {
43
- this .accessor = new ViewZoneChangeAccessor (textViewer );
44
- } catch (Exception e ) {
45
- e .printStackTrace ();
46
- }
46
+ textViewer .getTextWidget ().getDisplay ().syncExec (new Runnable () {
47
+
48
+ @ Override
49
+ public void run () {
50
+ CodeLensStrategy .this .accessor = new ViewZoneChangeAccessor (textViewer );
51
+ }
52
+ });
53
+
47
54
this ._lenses = new ArrayList <>();
48
55
}
49
56
@@ -55,16 +62,19 @@ private void onModelChange() {
55
62
if (symbolsPromise != null ) {
56
63
symbolsPromise .cancel (true );
57
64
}
58
- symbolsPromise = getCodeLensData (textViewer , targets );
59
- // symbols.exceptionally(ex -> ex.printStackTrace());
60
- symbolsPromise .thenAccept (symbols -> {
65
+ int modelCount = count .incrementAndGet ();
66
+ symbolsPromise = getCodeLensData (textViewer , targets , modelCount ).thenAccept (symbols -> {
61
67
renderCodeLensSymbols (symbols );
68
+ }).exceptionally (e -> {
69
+ e .printStackTrace ();
70
+ return null ;
62
71
});
72
+ ;
63
73
64
74
}
65
75
66
- private static CompletableFuture <Collection <CodeLensData >> getCodeLensData (ITextViewer textViewer ,
67
- List < String > targets ) {
76
+ private CompletableFuture <Collection <CodeLensData >> getCodeLensData (ITextViewer textViewer , List < String > targets ,
77
+ int modelCount ) {
68
78
return CompletableFuture .supplyAsync (() -> {
69
79
List <CodeLensData > symbols = new ArrayList <>();
70
80
for (String target : targets ) {
@@ -128,7 +138,14 @@ private void renderCodeLensSymbols(Collection<CodeLensData> symbols) {
128
138
while (groupsIndex < groups .size () && codeLensIndex < this ._lenses .size ()) {
129
139
130
140
int symbolsLineNumber = groups .get (groupsIndex ).get (0 ).getSymbol ().getRange ().startLineNumber ;
131
- int codeLensLineNumber = this ._lenses .get (codeLensIndex ).getLineNumber ();
141
+ int offset = this ._lenses .get (codeLensIndex ).getOffsetAtLine ();
142
+ int codeLensLineNumber = -1 ;
143
+ try {
144
+ codeLensLineNumber = offset != -1 ? textViewer .getDocument ().getLineOfOffset (offset ) + 1 : -1 ;
145
+ } catch (BadLocationException e ) {
146
+ // TODO Auto-generated catch block
147
+ e .printStackTrace ();
148
+ } // this._lenses.get(codeLensIndex).getLineNumber();
132
149
133
150
if (codeLensLineNumber < symbolsLineNumber ) {
134
151
this ._lenses .get (codeLensIndex ).dispose (helper , accessor );
@@ -151,7 +168,6 @@ private void renderCodeLensSymbols(Collection<CodeLensData> symbols) {
151
168
groupsIndex ++;
152
169
}
153
170
}
154
-
155
171
// Delete extra code lenses
156
172
while (codeLensIndex < this ._lenses .size ()) {
157
173
this ._lenses .get (codeLensIndex ).dispose (helper , accessor );
@@ -170,24 +186,35 @@ private void renderCodeLensSymbols(Collection<CodeLensData> symbols) {
170
186
}
171
187
172
188
// helper.commit(changeAccessor);
173
-
189
+ // Display.getDefault().asyncExec(() -> {
190
+ //// this._lenses.forEach((lens) -> {
191
+ //// lens.redraw(accessor);
192
+ //// });
193
+ // textViewer.getTextWidget().redraw();
194
+ // });
174
195
_onViewportChanged ();
175
196
}
176
197
177
198
private void _onViewportChanged () {
178
199
List <List <CodeLensData >> toResolve = new ArrayList <>();
179
200
List <CodeLens > lenses = new ArrayList <>();
180
201
181
- this ._lenses .forEach ((lens ) -> {
202
+ Integer topMargin = null ;
203
+ for (CodeLens lens : _lenses ) {
182
204
List <CodeLensData > request = lens .computeIfNecessary (null );
183
205
if (request != null ) {
184
206
toResolve .add (request );
185
207
lenses .add (lens );
208
+
209
+ Integer top = lens .getTopMargin ();
210
+ if (top != null ) {
211
+ topMargin = top ;
212
+ }
186
213
}
187
- });
214
+ }
188
215
189
216
if (toResolve .isEmpty ()) {
190
- return ;
217
+ // return;
191
218
}
192
219
193
220
int i = 0 ;
@@ -203,19 +230,40 @@ private void _onViewportChanged() {
203
230
i ++;
204
231
}
205
232
233
+ final Integer top = topMargin ;
206
234
Display .getDefault ().syncExec (() -> {
207
- this ._lenses .forEach ((lens ) -> {
208
- lens .redraw (accessor );
209
- });
235
+ StyledText styledText = textViewer .getTextWidget ();
236
+ if (invalidateTextPresentation ) {
237
+ // if (top != null && styledText.getTopMargin() != top) {
238
+ // try {
239
+ // Field f = styledText.getClass().getDeclaredField("topMargin");
240
+ // f.setAccessible(true);
241
+ // f.set(styledText, top);
242
+ // } catch (Exception e) {
243
+ // // TODO Auto-generated catch block
244
+ // e.printStackTrace();
245
+ // }
246
+ // }
247
+ textViewer .invalidateTextPresentation ();
248
+ } else {
249
+ if (top != null && styledText .getTopMargin () != top ) {
250
+ styledText .setTopMargin (top );
251
+ } else {
252
+ int offset = styledText .getCaretOffset ();
253
+ StyledTextPatcher .setVariableLineHeight (styledText );
254
+ styledText .redraw ();
255
+ styledText .setCaretOffset (offset );
256
+ }
257
+ }
210
258
});
211
259
}
212
260
213
- public CodeLensContribution addTarget (String target ) {
261
+ public CodeLensStrategy addTarget (String target ) {
214
262
targets .add (target );
215
263
return this ;
216
264
}
217
265
218
- public CodeLensContribution removeTarget (String target ) {
266
+ public CodeLensStrategy removeTarget (String target ) {
219
267
targets .remove (target );
220
268
return this ;
221
269
}
@@ -224,32 +272,20 @@ public void dispose() {
224
272
225
273
}
226
274
227
- /*
228
- * private Collection<CompletableFuture<CodeLensData>>
229
- * getCodeLensData(ITextViewer textViewer) {
230
- *
231
- * Collection<CodeLensData> symbols = new ArrayList<>(); String
232
- * contentTypeId = "";
233
- *
234
- * // Collection<CompletableFuture<CodeLensData>> promises =
235
- * registry.all(contentTypeId).stream().map(provider -> { //
236
- * CompletableFuture<CodeLensData> promise =
237
- * CompletableFuture.supplyAsync(() -> { //
238
- * provider.provideCodeLenses(textViewer); // });
239
- *
240
- * // // // // new CompletableFuture<CodeLensData>(); // //promise. // //
241
- * promise.thenAccept(result -> { // if (result != null) { // for (ICodeLens
242
- * symbol : result) { // symbols.add(new CodeLensData(symbol, provider)); //
243
- * } // } // }) return promise; }).collect(Collectors.toList());
244
- *
245
- * for (
246
- *
247
- * ICodeLensProvider provider : providers) { ICodeLens[] result =
248
- * provider.provideCodeLenses(textViewer); if (result != null) { for
249
- * (ICodeLens symbol : result) { symbols.add(new CodeLensData(symbol,
250
- * provider)); } } }
251
- *
252
- * }
253
- */
275
+ @ Override
276
+ public void setDocument (IDocument document ) {
277
+ // TODO Auto-generated method stub
278
+
279
+ }
280
+
281
+ @ Override
282
+ public void reconcile (DirtyRegion dirtyRegion , IRegion subRegion ) {
283
+ onModelChange ();
284
+ }
285
+
286
+ @ Override
287
+ public void reconcile (IRegion partition ) {
288
+ onModelChange ();
289
+ }
254
290
255
291
}
0 commit comments