@@ -13,6 +13,8 @@ import { RunOnceScheduler } from 'vs/base/common/async';
13
13
import { Range } from 'vs/editor/common/core/range' ;
14
14
import { Emitter } from 'vs/base/common/event' ;
15
15
import { binarySearch } from 'vs/base/common/arrays' ;
16
+ import { FoldingController } from 'vs/editor/contrib/folding/browser/folding' ;
17
+ import { FoldingModel } from 'vs/editor/contrib/folding/browser/foldingModel' ;
16
18
17
19
export class StickyRange {
18
20
constructor (
@@ -92,7 +94,24 @@ export class StickyLineCandidateProvider extends Disposable {
92
94
if ( token . isCancellationRequested ) {
93
95
return ;
94
96
}
95
- this . _outlineModel = StickyOutlineElement . fromOutlineModel ( outlineModel , - 1 ) ;
97
+ if ( outlineModel . children . size !== 0 ) {
98
+ this . _outlineModel = StickyOutlineElement . fromOutlineModel ( outlineModel , - 1 ) ;
99
+ } else {
100
+ const foldingController = FoldingController . get ( this . _editor ) ;
101
+ const foldingModel = await foldingController ?. getFoldingModel ( ) ;
102
+ if ( token . isCancellationRequested ) {
103
+ return ;
104
+ }
105
+ if ( foldingModel && foldingModel . regions . length !== 0 ) {
106
+ this . _outlineModel = StickyOutlineElement . fromFoldingModel ( foldingModel ) ;
107
+ } else {
108
+ this . _outlineModel = new StickyOutlineElement (
109
+ new StickyRange ( - 1 , - 1 ) ,
110
+ [ ] ,
111
+ undefined
112
+ ) ;
113
+ }
114
+ }
96
115
this . _modelVersionId = modelVersionId ;
97
116
}
98
117
}
@@ -191,9 +210,44 @@ class StickyOutlineElement {
191
210
}
192
211
return new StickyOutlineElement (
193
212
range ,
194
- children
213
+ children ,
214
+ undefined
195
215
) ;
196
216
}
217
+
218
+ public static fromFoldingModel ( foldingModel : FoldingModel ) : StickyOutlineElement {
219
+ const regions = foldingModel . regions ;
220
+ const length = regions . length ;
221
+ let range : StickyRange | undefined ;
222
+ const stackOfParents : StickyRange [ ] = [ ] ;
223
+
224
+ const stickyOutlineElement = new StickyOutlineElement (
225
+ undefined ,
226
+ [ ] ,
227
+ undefined
228
+ ) ;
229
+ let parentStickyOutlineElement = stickyOutlineElement ;
230
+
231
+ for ( let i = 0 ; i < length ; i ++ ) {
232
+ range = new StickyRange ( regions . getStartLineNumber ( i ) , regions . getEndLineNumber ( i ) ) ;
233
+ while ( stackOfParents . length !== 0 && ( range . startLineNumber < stackOfParents [ stackOfParents . length - 1 ] . startLineNumber || range . endLineNumber > stackOfParents [ stackOfParents . length - 1 ] . endLineNumber ) ) {
234
+ stackOfParents . pop ( ) ;
235
+ if ( parentStickyOutlineElement . parent !== undefined ) {
236
+ parentStickyOutlineElement = parentStickyOutlineElement . parent ;
237
+ }
238
+ }
239
+ const child = new StickyOutlineElement (
240
+ range ,
241
+ [ ] ,
242
+ parentStickyOutlineElement
243
+ ) ;
244
+ parentStickyOutlineElement . children . push ( child ) ;
245
+ parentStickyOutlineElement = child ;
246
+ stackOfParents . push ( range ) ;
247
+ }
248
+ return stickyOutlineElement ;
249
+ }
250
+
197
251
constructor (
198
252
/**
199
253
* Range of line numbers spanned by the current scope
@@ -202,7 +256,11 @@ class StickyOutlineElement {
202
256
/**
203
257
* Must be sorted by start line number
204
258
*/
205
- public readonly children : readonly StickyOutlineElement [ ] ,
259
+ public readonly children : StickyOutlineElement [ ] ,
260
+ /**
261
+ * Parent sticky outline element
262
+ */
263
+ public readonly parent : StickyOutlineElement | undefined
206
264
) {
207
265
}
208
266
}
0 commit comments