public static NormalizedSnapshotSpanCollection MapDownToR(this ITextView textView, SnapshotSpan span) {
if (textView.BufferGraph == null) {
// Unit test case
return new NormalizedSnapshotSpanCollection(span);
}
// There's no convenient method to get all of the lower buffers this span matches to,
// any of the methods will only map down to a single buffer. So here we map the span
// down, map the span back up to get the range in the top buffer, and then we continue
// searching from the end of the span that we mapped down and back up. We stop when
// we hit the end of the requested spans or when we find no more spans.
List<SnapshotSpan> spans = new List<SnapshotSpan>();
for (;;) {
// map down
var languageSpans = textView.BufferGraph.MapDownToFirstMatch(
span,
SpanTrackingMode.EdgeExclusive,
x => x.ContentType.IsOfType(RContentTypeDefinition.ContentType)
);
// could yield multiple spans, but in the interactive only ever yields one
int newStart = span.End;
foreach (var lowerSpan in languageSpans) {
// map back up to get the end in the top buffer
foreach (var upperSpan in textView.BufferGraph.MapUpToBuffer(
lowerSpan,
SpanTrackingMode.EdgeInclusive,
textView.TextBuffer
)) {
spans.Add(upperSpan);
newStart = upperSpan.End;
}
}
if (newStart >= span.End) {
break;
}
// update the span that we're searching for to start at the end of the last span we found
span = new SnapshotSpan(span.Snapshot, Span.FromBounds(newStart, span.End));
}
return new NormalizedSnapshotSpanCollection(spans);
}