@@ -12,7 +12,6 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
12
12
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
- import { binarySearch } from 'vs/base/common/arrays' ;
16
15
17
16
export class StickyRange {
18
17
constructor (
@@ -97,26 +96,43 @@ export class StickyLineCandidateProvider extends Disposable {
97
96
}
98
97
}
99
98
100
- // consider the case when index = -length - 1
101
- private updatedIndex ( index : number ) {
102
- if ( index === - 1 ) {
103
- index = 0 ;
104
- } else if ( index < 0 ) {
105
- index = - index - 2 ;
99
+ private customBinarySearch ( model : readonly StickyOutlineElement [ ] , startLine : number ) {
100
+
101
+ // Binary search
102
+ let result ;
103
+ let low = 0 , high = model . length - 1 ;
104
+ while ( low <= high ) {
105
+ const mid = ( ( low + high ) / 2 ) | 0 ;
106
+ const comp = model [ mid ] . range ?. startLineNumber as number - startLine ;
107
+ if ( comp < 0 ) {
108
+ low = mid + 1 ;
109
+ } else if ( comp > 0 ) {
110
+ high = mid - 1 ;
111
+ } else {
112
+ result = mid ;
113
+ break ;
114
+ }
115
+ }
116
+ if ( ! result ) { result = - ( low + 1 ) ; }
117
+
118
+ // Update index
119
+ if ( result === - 1 ) {
120
+ result = 0 ;
121
+ } else if ( result < 0 ) {
122
+ result = - result - 2 ;
106
123
}
107
- return index ;
124
+ return result ;
108
125
}
109
126
110
127
public getCandidateStickyLinesIntersectingFromOutline ( range : StickyRange , outlineModel : StickyOutlineElement , result : StickyLineCandidate [ ] , depth : number , lastStartLineNumber : number ) : void {
111
128
if ( ! outlineModel || outlineModel . children . length === 0 ) {
112
129
return ;
113
130
}
114
131
let lastLine = lastStartLineNumber ;
115
- const childrenStartLines = outlineModel . children . filter ( child => { return child . range ?. startLineNumber !== child . range ?. endLineNumber ; } ) . map ( child => child . range ?. startLineNumber as number ) ;
116
- const indexLower = this . updatedIndex ( binarySearch ( childrenStartLines , range . startLineNumber , ( a : number , b : number ) => { return a - b ; } ) ) ;
117
- const indexUpper = this . updatedIndex ( binarySearch ( childrenStartLines , range . startLineNumber + depth , ( a : number , b : number ) => { return a - b ; } ) ) ;
118
- for ( let i = indexLower ; i <= indexUpper ; i ++ ) {
119
- const child = outlineModel . children . filter ( child => { return child . range ?. startLineNumber !== child . range ?. endLineNumber ; } ) [ i ] ;
132
+ const lowerBound = this . customBinarySearch ( outlineModel . children , range . startLineNumber ) ;
133
+ const upperBound = this . customBinarySearch ( outlineModel . children , range . startLineNumber + depth ) ;
134
+ for ( let i = lowerBound ; i <= upperBound ; i ++ ) {
135
+ const child = outlineModel . children [ i ] ;
120
136
if ( child && child . range ) {
121
137
const childStartLine = child . range . startLineNumber ;
122
138
const childEndLine = child . range . endLineNumber ;
@@ -151,9 +167,13 @@ export class StickyLineCandidateProvider extends Disposable {
151
167
152
168
class StickyOutlineElement {
153
169
public static fromOutlineModel ( outlineModel : OutlineModel | OutlineElement | OutlineGroup ) : StickyOutlineElement {
154
- const children = [ ...outlineModel . children . values ( ) ] . map ( child =>
155
- StickyOutlineElement . fromOutlineModel ( child )
156
- ) ;
170
+ const children = [ ...outlineModel . children . values ( ) ] . map ( child => {
171
+ if ( child instanceof OutlineElement && child . symbol . selectionRange . startLineNumber !== child . symbol . range . endLineNumber || child instanceof OutlineGroup || child instanceof OutlineModel ) {
172
+ return StickyOutlineElement . fromOutlineModel ( child ) ;
173
+ } else {
174
+ return ;
175
+ }
176
+ } ) . filter ( ( child ) => ! ! child ) as StickyOutlineElement [ ] ;
157
177
children . sort ( ( child1 , child2 ) => {
158
178
if ( ! child1 . range || ! child2 . range ) {
159
179
return 1 ;
0 commit comments