@@ -173,7 +173,7 @@ namespace ts {
173
173
return spans ;
174
174
}
175
175
176
- function matchTextChunk ( candidate : string , chunk : TextChunk , stringToWordSpans : Map < TextSpan [ ] > ) : PatternMatch {
176
+ function matchTextChunk ( candidate : string , chunk : TextChunk , stringToWordSpans : Map < TextSpan [ ] > ) : PatternMatch | undefined {
177
177
const index = indexOfIgnoringCase ( candidate , chunk . textLowerCase ) ;
178
178
if ( index === 0 ) {
179
179
if ( chunk . text . length === candidate . length ) {
@@ -188,61 +188,48 @@ namespace ts {
188
188
}
189
189
}
190
190
191
- const isLowercase = chunk . isLowerCase ;
192
- if ( isLowercase ) {
193
- if ( index > 0 ) {
194
- // c) If the part is entirely lowercase, then check if it is contained anywhere in the
195
- // candidate in a case insensitive manner. If so, return that there was a substring
196
- // match.
197
- //
198
- // Note: We only have a substring match if the lowercase part is prefix match of some
199
- // word part. That way we don't match something like 'Class' when the user types 'a'.
200
- // But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
201
- const wordSpans = getWordSpans ( candidate , stringToWordSpans ) ;
202
- for ( const span of wordSpans ) {
203
- if ( partStartsWith ( candidate , span , chunk . text , /*ignoreCase:*/ true ) ) {
204
- return createPatternMatch ( PatternMatchKind . substring , /*isCaseSensitive:*/ partStartsWith ( candidate , span , chunk . text , /*ignoreCase:*/ false ) ) ;
205
- }
191
+ if ( chunk . isLowerCase ) {
192
+ if ( index === - 1 ) return undefined ;
193
+ // c) If the part is entirely lowercase, then check if it is contained anywhere in the
194
+ // candidate in a case insensitive manner. If so, return that there was a substring
195
+ // match.
196
+ //
197
+ // Note: We only have a substring match if the lowercase part is prefix match of some
198
+ // word part. That way we don't match something like 'Class' when the user types 'a'.
199
+ // But we would match 'FooAttribute' (since 'Attribute' starts with 'a').
200
+ const wordSpans = getWordSpans ( candidate , stringToWordSpans ) ;
201
+ for ( const span of wordSpans ) {
202
+ if ( partStartsWith ( candidate , span , chunk . text , /*ignoreCase:*/ true ) ) {
203
+ return createPatternMatch ( PatternMatchKind . substring , /*isCaseSensitive:*/ partStartsWith ( candidate , span , chunk . text , /*ignoreCase:*/ false ) ) ;
206
204
}
207
205
}
206
+ // d) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
207
+ // We could check every character boundary start of the candidate for the pattern. However, that's
208
+ // an m * n operation in the wost case. Instead, find the first instance of the pattern
209
+ // substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
210
+ // filter the list based on a substring that starts on a capital letter and also with a lowercase one.
211
+ // (Pattern: fogbar, Candidate: quuxfogbarFogBar).
212
+ if ( chunk . text . length < candidate . length && isUpperCaseLetter ( candidate . charCodeAt ( index ) ) ) {
213
+ return createPatternMatch ( PatternMatchKind . substring , /*isCaseSensitive:*/ false ) ;
214
+ }
208
215
}
209
216
else {
210
- // d ) If the part was not entirely lowercase, then check if it is contained in the
217
+ // e ) If the part was not entirely lowercase, then check if it is contained in the
211
218
// candidate in a case *sensitive* manner. If so, return that there was a substring
212
219
// match.
213
220
if ( candidate . indexOf ( chunk . text ) > 0 ) {
214
221
return createPatternMatch ( PatternMatchKind . substring , /*isCaseSensitive:*/ true ) ;
215
222
}
216
- }
217
-
218
- if ( ! isLowercase ) {
219
- // e) If the part was not entirely lowercase, then attempt a camel cased match as well.
223
+ // f) If the part was not entirely lowercase, then attempt a camel cased match as well.
220
224
if ( chunk . characterSpans . length > 0 ) {
221
225
const candidateParts = getWordSpans ( candidate , stringToWordSpans ) ;
222
226
const isCaseSensitive = tryCamelCaseMatch ( candidate , candidateParts , chunk , /*ignoreCase:*/ false ) ? true
223
- : tryCamelCaseMatch ( candidate , candidateParts , chunk , /*ignoreCase:*/ true ) ? false : undefined ;
227
+ : tryCamelCaseMatch ( candidate , candidateParts , chunk , /*ignoreCase:*/ true ) ? false : undefined ;
224
228
if ( isCaseSensitive !== undefined ) {
225
229
return createPatternMatch ( PatternMatchKind . camelCase , isCaseSensitive ) ;
226
230
}
227
231
}
228
232
}
229
-
230
- if ( isLowercase ) {
231
- // f) Is the pattern a substring of the candidate starting on one of the candidate's word boundaries?
232
-
233
- // We could check every character boundary start of the candidate for the pattern. However, that's
234
- // an m * n operation in the wost case. Instead, find the first instance of the pattern
235
- // substring, and see if it starts on a capital letter. It seems unlikely that the user will try to
236
- // filter the list based on a substring that starts on a capital letter and also with a lowercase one.
237
- // (Pattern: fogbar, Candidate: quuxfogbarFogBar).
238
- if ( chunk . text . length < candidate . length ) {
239
- if ( index > 0 && isUpperCaseLetter ( candidate . charCodeAt ( index ) ) ) {
240
- return createPatternMatch ( PatternMatchKind . substring , /*isCaseSensitive:*/ false ) ;
241
- }
242
- }
243
- }
244
-
245
- return undefined ;
246
233
}
247
234
248
235
function containsSpaceOrAsterisk ( text : string ) : boolean {
@@ -287,24 +274,26 @@ namespace ts {
287
274
// b) Check if the word is a prefix of the candidate, in a case insensitive or
288
275
// sensitive manner. If it does, return that there was a prefix match.
289
276
//
290
- // c) If the word is entirely lowercase, then check if it is contained anywhere in the
291
- // candidate in a case insensitive manner. If so, return that there was a substring
292
- // match.
277
+ // If the word is entirely lowercase:
278
+ // c) Then check if it is contained anywhere in the
279
+ // candidate in a case insensitive manner. If so, return that there was a substring
280
+ // match.
293
281
//
294
- // Note: We only have a substring match if the lowercase part is prefix match of
295
- // some word part. That way we don't match something like 'Class' when the user
296
- // types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
297
- // 'a').
282
+ // Note: We only have a substring match if the lowercase part is prefix match of
283
+ // some word part. That way we don't match something like 'Class' when the user
284
+ // types 'a'. But we would match 'FooAttribute' (since 'Attribute' starts with
285
+ // 'a').
298
286
//
299
- // d) If the word was not entirely lowercase, then check if it is contained in the
300
- // candidate in a case *sensitive* manner. If so, return that there was a substring
301
- // match.
287
+ // d) The word is all lower case. Is it a case insensitive substring of the candidate starting
288
+ // on a part boundary of the candidate?
302
289
//
303
- // e) If the word was not entirely lowercase, then attempt a camel cased match as
304
- // well.
290
+ // Else:
291
+ // e) If the word was not entirely lowercase, then check if it is contained in the
292
+ // candidate in a case *sensitive* manner. If so, return that there was a substring
293
+ // match.
305
294
//
306
- // f) The word is all lower case. Is it a case insensitive substring of the candidate starting
307
- // on a part boundary of the candidate?
295
+ // f) If the word was not entirely lowercase, then attempt a camel cased match as
296
+ // well.
308
297
//
309
298
// Only if all words have some sort of match is the pattern considered matched.
310
299
0 commit comments