private static void SplitMapDownToFirstMatchNoTrack(FrugalList <SnapshotSpan> unmappedSpans, Predicate <ITextBuffer> match, IList <SnapshotSpan> mappedSpans, bool mapByContentType) { ITextSnapshot matchingSnapshot = null; while (unmappedSpans.Count > 0) { SnapshotSpan span = unmappedSpans[unmappedSpans.Count - 1]; unmappedSpans.RemoveAt(unmappedSpans.Count - 1); if (span.Snapshot == matchingSnapshot) { mappedSpans.Add(span); } else if (match(span.Snapshot.TextBuffer)) { mappedSpans.Add(span); matchingSnapshot = span.Snapshot; } else { IProjectionSnapshot spanSnapshotAsProjection = span.Snapshot as IProjectionSnapshot; if (spanSnapshotAsProjection != null && (!mapByContentType || span.Snapshot.TextBuffer.ContentType.IsOfType("projection"))) { unmappedSpans.AddRange(spanSnapshotAsProjection.MapToSourceSnapshots(span)); } } } }
private static Span MapDownToSnapshot( Span span, IProjectionSnapshot start, ITextSnapshot target ) { var sourceSpans = new Queue <SnapshotSpan>(start.MapToSourceSnapshots(span)); while (true) { var sourceSpan = sourceSpans.Dequeue(); if (sourceSpan.Snapshot == target) { return(sourceSpan.Span); } else if (sourceSpan.Snapshot is IProjectionSnapshot) { foreach ( var s in (sourceSpan.Snapshot as IProjectionSnapshot).MapToSourceSnapshots( sourceSpan.Span ) ) { sourceSpans.Enqueue(s); } } } }
internal static StringRebuilder StringRebuilderFromSnapshotSpan(SnapshotSpan span) { TextSnapshot snapshot = span.Snapshot as TextSnapshot; if (snapshot != null) { return(snapshot.Content.Substring(span)); } IProjectionSnapshot projectionSnapshot = span.Snapshot as IProjectionSnapshot; if (projectionSnapshot != null) { StringRebuilder content = SimpleStringRebuilder.Create(string.Empty); foreach (var childSpan in projectionSnapshot.MapToSourceSnapshots(span)) { content = content.Append(StringRebuilderFromSnapshotSpan(childSpan)); } return(content); } //The we don't know what to do fallback. This should never be called unless someone provides a new snapshot //implementation. return(SimpleStringRebuilder.Create(span.GetText())); }
internal static void MapDownToBufferNoTrack(SnapshotSpan sourceSpan, ITextBuffer targetBuffer, IList <SnapshotSpan> mappedSpans, bool mapByContentType = false) { // Most of the time, the sourceSpan will map to the targetBuffer as a single span, rather than being split. // Since this method is called a lot, we'll assume first that we'll get a single span and don't need to // allocate a stack to keep track of unmapped spans. If that fails we'll fall back on the more expensive approach. // Scroll around for a while and this saves a bunch of allocations. SnapshotSpan mappedSpan = sourceSpan; while (true) { if (mappedSpan.Snapshot.TextBuffer == targetBuffer) { mappedSpans.Add(mappedSpan); return; } else { IProjectionSnapshot mappedSpanProjectionSnapshot = mappedSpan.Snapshot as IProjectionSnapshot; if (mappedSpanProjectionSnapshot != null && (!mapByContentType || mappedSpanProjectionSnapshot.ContentType.IsOfType("projection"))) { var mappedDownSpans = mappedSpanProjectionSnapshot.MapToSourceSnapshots(mappedSpan); if (mappedDownSpans.Count == 1) { mappedSpan = mappedDownSpans[0]; continue; } else if (mappedDownSpans.Count == 0) { return; } else { // the projection mapping resulted in more than one span FrugalList <SnapshotSpan> unmappedSpans = new FrugalList <SnapshotSpan>(mappedDownSpans); SplitMapDownToBufferNoTrack(unmappedSpans, targetBuffer, mappedSpans, mapByContentType); return; } } else { // either it's a projection buffer we can't look through, or it's // an ordinary buffer that didn't match return; } } } }
private static void MapDownToGround(IList <SnapshotSpan> spans, Dictionary <ITextSnapshot, List <Span> > groundSourceSpansMap) { foreach (SnapshotSpan span in spans) { IProjectionSnapshot projSnap = span.Snapshot as IProjectionSnapshot; if (projSnap == null) { List <Span> groundSpans; if (!groundSourceSpansMap.TryGetValue(span.Snapshot, out groundSpans)) { groundSpans = new List <Span>(); groundSourceSpansMap.Add(span.Snapshot, groundSpans); } groundSpans.Add(span); } else { MapDownToGround(projSnap.MapToSourceSnapshots(span), groundSourceSpansMap); } } }
private static void SplitMapDownToBufferNoTrack(FrugalList <SnapshotSpan> unmappedSpans, ITextBuffer targetBuffer, IList <SnapshotSpan> mappedSpans, bool mapByContentType) { while (unmappedSpans.Count > 0) { SnapshotSpan span = unmappedSpans[unmappedSpans.Count - 1]; unmappedSpans.RemoveAt(unmappedSpans.Count - 1); if (span.Snapshot.TextBuffer == targetBuffer) { mappedSpans.Add(span); } else { IProjectionSnapshot spanSnapshotAsProjection = span.Snapshot as IProjectionSnapshot; if (spanSnapshotAsProjection != null && (!mapByContentType || span.Snapshot.TextBuffer.ContentType.IsOfType("projection"))) { unmappedSpans.AddRange(spanSnapshotAsProjection.MapToSourceSnapshots(span)); } } } }
private static void ExtendSourceMap(IProjectionSnapshot sourceSnapshot, Span sourceSpan, bool mapByContentType, Dictionary <ITextSnapshot, IList <Span> > allSpans) { var childSpans = sourceSnapshot.MapToSourceSnapshots(sourceSpan); for (int c = 0; (c < childSpans.Count); ++c) { var childSpan = childSpans[c]; if (!allSpans.TryGetValue(childSpan.Snapshot, out IList <Span> spans)) { spans = new FrugalList <Span>(); allSpans.Add(childSpan.Snapshot, spans); } spans.Add(childSpan); if ((childSpan.Snapshot is IProjectionSnapshot childProjectionSnapshot) && (!mapByContentType || childProjectionSnapshot.TextBuffer.ContentType.IsOfType("projection"))) { ExtendSourceMap(childProjectionSnapshot, childSpan, mapByContentType, allSpans); } } }
private static FrugalList <SnapshotSpan> MapDownOneLevel(FrugalList <SnapshotSpan> inputSpans, Predicate <ITextSnapshot> match, ref ITextSnapshot chosenSnapshot, ref FrugalList <Span> targetSpans) { FrugalList <SnapshotSpan> downSpans = new FrugalList <SnapshotSpan>(); foreach (SnapshotSpan inputSpan in inputSpans) { IProjectionBufferBase projBuffer = (IProjectionBufferBase)inputSpan.Snapshot.TextBuffer; IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count > 0) { IList <SnapshotSpan> mappedSpans = projSnap.MapToSourceSnapshots(inputSpan); for (int s = 0; s < mappedSpans.Count; ++s) { SnapshotSpan mappedSpan = mappedSpans[s]; ITextBuffer mappedBuffer = mappedSpan.Snapshot.TextBuffer; if (mappedBuffer.CurrentSnapshot == chosenSnapshot) { targetSpans.Add(mappedSpan.Span); } else if (chosenSnapshot == null && match(mappedBuffer.CurrentSnapshot)) { chosenSnapshot = mappedBuffer.CurrentSnapshot; targetSpans.Add(mappedSpan.Span); } else { IProjectionBufferBase mappedProjBuffer = mappedBuffer as IProjectionBufferBase; if (mappedProjBuffer != null) { downSpans.Add(mappedSpan); } } } } } return(downSpans); }
private static Span MapDownToSnapshot(Span span, IProjectionSnapshot start, ITextSnapshot target) { var sourceSpans = new Queue<SnapshotSpan>(start.MapToSourceSnapshots(span)); while (true) { var sourceSpan = sourceSpans.Dequeue(); if (sourceSpan.Snapshot == target) { return sourceSpan.Span; } else if (sourceSpan.Snapshot is IProjectionSnapshot) { foreach (var s in (sourceSpan.Snapshot as IProjectionSnapshot).MapToSourceSnapshots(sourceSpan.Span)) { sourceSpans.Enqueue(s); } } } }