@@ -173,7 +173,7 @@ namespace ts {
173173 return spans ;
174174 }
175175
176- function matchTextChunk ( candidate : string , chunk : TextChunk , stringToWordSpans : Map < TextSpan [ ] > ) : PatternMatch {
176+ function matchTextChunk ( candidate : string , chunk : TextChunk , stringToWordSpans : Map < TextSpan [ ] > ) : PatternMatch | undefined {
177177 const index = indexOfIgnoringCase ( candidate , chunk . textLowerCase ) ;
178178 if ( index === 0 ) {
179179 if ( chunk . text . length === candidate . length ) {
@@ -188,61 +188,48 @@ namespace ts {
188188 }
189189 }
190190
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 ) ) ;
206204 }
207205 }
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+ }
208215 }
209216 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
211218 // candidate in a case *sensitive* manner. If so, return that there was a substring
212219 // match.
213220 if ( candidate . indexOf ( chunk . text ) > 0 ) {
214221 return createPatternMatch ( PatternMatchKind . substring , /*isCaseSensitive:*/ true ) ;
215222 }
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.
220224 if ( chunk . characterSpans . length > 0 ) {
221225 const candidateParts = getWordSpans ( candidate , stringToWordSpans ) ;
222226 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 ;
224228 if ( isCaseSensitive !== undefined ) {
225229 return createPatternMatch ( PatternMatchKind . camelCase , isCaseSensitive ) ;
226230 }
227231 }
228232 }
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 ;
246233 }
247234
248235 function containsSpaceOrAsterisk ( text : string ) : boolean {
@@ -287,24 +274,26 @@ namespace ts {
287274 // b) Check if the word is a prefix of the candidate, in a case insensitive or
288275 // sensitive manner. If it does, return that there was a prefix match.
289276 //
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.
293281 //
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').
298286 //
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?
302289 //
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.
305294 //
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.
308297 //
309298 // Only if all words have some sort of match is the pattern considered matched.
310299
0 commit comments