private static NavigateToMatchKind GetNavigateToMatchKind( bool containsDots, PatternMatches matchResult) { // NOTE(cyrusn): Unfortunately, the editor owns how sorting of NavigateToItems works, // and they only provide four buckets for sorting items before they sort by the name // of the items. Because of this, we only have coarse granularity for bucketing things. // // So the question becomes: what do we do if we have multiple match results, and we // need to map to a single MatchKind. // // First, consider a main reason we have multiple match results. And this happened // when the user types a dotted name (like "Microsoft.CodeAnalysis.ISymbol"). Such // a name would match actual entities: Microsoft.CodeAnalysis.ISymbol *and* // Microsoft.CodeAnalysis.IAliasSymbol. The first will be an [Exact, Exact, Exact] // match, and the second will be an [Exact, Exact, CamelCase] match. In this // case our belief is that the names will go from least specific to most specific. // So, the left items may match lots of stuff, while the rightmost items will match // a smaller set of items. As such, we use the last pattern match to try to decide // what type of editor MatchKind to map to. if (containsDots) { var lastResult = matchResult.CandidateMatches.LastOrNullable(); if (lastResult.HasValue) { switch (lastResult.Value.Kind) { case PatternMatchKind.Exact: return NavigateToMatchKind.Exact; case PatternMatchKind.Prefix: return NavigateToMatchKind.Prefix; case PatternMatchKind.Substring: return NavigateToMatchKind.Substring; } } } else { // If it wasn't a dotted name, and we have multiple results, that's because they // had a something like a space separated pattern. In that case, there's no // clear indication as to what is the most important part of the pattern. So // we make the result as good as any constituent part. if (matchResult.Any(r => r.Kind == PatternMatchKind.Exact)) { return NavigateToMatchKind.Exact; } if (matchResult.Any(r => r.Kind == PatternMatchKind.Prefix)) { return NavigateToMatchKind.Prefix; } if (matchResult.Any(r => r.Kind == PatternMatchKind.Substring)) { return NavigateToMatchKind.Substring; } } return NavigateToMatchKind.Regular; }