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())); }
private static IEnumerable <Span> MapUpToSnapshotRecursive( SnapshotSpan start, IProjectionSnapshot target ) { foreach (var source in target.SourceSnapshots) { if (source == start.Snapshot) { foreach (var result in target.MapFromSourceSnapshot(start)) { yield return(result); } } else if (source is IProjectionSnapshot sourceProjection) { foreach (var span in MapUpToSnapshotRecursive(start, sourceProjection)) { foreach ( var result in target.MapFromSourceSnapshot( new SnapshotSpan(source, span) ) ) { yield return(result); } } } } yield break; }
private bool TryGetCurrentLanguageBufferExtent(IProjectionSnapshot projectionSnapshot, out Span result) { if (projectionSnapshot.SpanCount == 0) { result = default(Span); return(false); } // the last source snapshot is always a projection of a language buffer: var snapshot = projectionSnapshot.GetSourceSpan(projectionSnapshot.SpanCount - 1).Snapshot; if (snapshot.TextBuffer != _currentLanguageBuffer) { result = default(Span); return(false); } SnapshotPoint start = new SnapshotPoint(snapshot, 0); SnapshotPoint end = new SnapshotPoint(snapshot, snapshot.Length); // projection of the previous version of current language buffer snapshot: var surfaceSpans = projectionSnapshot.MapFromSourceSnapshot(new SnapshotSpan(start, end)); // the language buffer might be projected to multiple surface lines: Debug.Assert(surfaceSpans.Count > 0); result = new Span(surfaceSpans[0].Start, surfaceSpans.Last().End); return(true); }
public static void MapUpToSnapshotNoTrack(ITextSnapshot targetSnapshot, SnapshotSpan anchor, IList <SnapshotSpan> mappedSpans) { if (anchor.Snapshot == targetSnapshot) { mappedSpans.Add(anchor); } else { IProjectionSnapshot targetAsProjection = targetSnapshot as IProjectionSnapshot; if (targetAsProjection != null) { var sourceSnapshots = targetAsProjection.SourceSnapshots; for (int s = 0; s < sourceSnapshots.Count; ++s) { FrugalList <SnapshotSpan> downSpans = new FrugalList <SnapshotSpan>(); MapUpToSnapshotNoTrack(sourceSnapshots[s], anchor, downSpans); for (int ds = 0; ds < downSpans.Count; ++ds) { var upSpans = targetAsProjection.MapFromSourceSnapshot(downSpans[ds]); for (int us = 0; us < upSpans.Count; ++us) { mappedSpans.Add(new SnapshotSpan(targetSnapshot, upSpans[us])); } } } } } }
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)); } } } }
public static SnapshotPoint?MapUpToSnapshotNoTrack(ITextSnapshot targetSnapshot, SnapshotPoint anchor, PositionAffinity affinity) { if (anchor.Snapshot == targetSnapshot) { return(anchor); } else { IProjectionSnapshot targetAsProjection = targetSnapshot as IProjectionSnapshot; if (targetAsProjection != null) { var sourceSnapshots = targetAsProjection.SourceSnapshots; for (int s = 0; s < sourceSnapshots.Count; ++s) { SnapshotPoint?downPoint = MapUpToSnapshotNoTrack(sourceSnapshots[s], anchor, affinity); if (downPoint.HasValue) { SnapshotPoint?result = targetAsProjection.MapFromSourceSnapshot(downPoint.Value, affinity); if (result.HasValue) { return(result); } } } } } return(null); }
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); } } } }
public static ProjectionSpanDifference DiffSourceSpans(IDifferenceService diffService, IProjectionSnapshot left, IProjectionSnapshot right) { if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } if (!object.ReferenceEquals(left.TextBuffer, right.TextBuffer)) { throw new ArgumentException("left does not belong to the same text buffer as right"); } ProjectionSpanDiffer differ = new ProjectionSpanDiffer (diffService, left.GetSourceSpans(), right.GetSourceSpans()); return(new ProjectionSpanDifference(differ.GetDifferences(), differ.InsertedSpans, differ.DeletedSpans)); }
public async Task <DataTipInfo> GetDebugInfoAsync(SnapshotPoint snapshotPoint, CancellationToken cancellationToken) { var analysisDocument = snapshotPoint.Snapshot.AsText().GetOpenDocumentInCurrentContextWithChanges(); IProjectionSnapshot projectionSnapshot = null; if (analysisDocument == null) { projectionSnapshot = snapshotPoint.Snapshot as IProjectionSnapshot; if (projectionSnapshot != null) { snapshotPoint = projectionSnapshot.MapToSourceSnapshot(snapshotPoint.Position); analysisDocument = snapshotPoint.Snapshot.AsText().GetOpenDocumentInCurrentContextWithChanges(); } } if (analysisDocument == null) { return(default(DataTipInfo)); } var debugInfoService = analysisDocument.GetLanguageService <Microsoft.CodeAnalysis.Editor.Implementation.Debugging.ILanguageDebugInfoService> (); if (debugInfoService == null) { return(default(DataTipInfo)); } var tipInfo = await debugInfoService.GetDataTipInfoAsync(analysisDocument, snapshotPoint.Position, cancellationToken).ConfigureAwait(false); var text = tipInfo.Text; if (text == null && !tipInfo.IsDefault) { text = snapshotPoint.Snapshot.GetText(tipInfo.Span.Start, tipInfo.Span.Length); } var semanticModel = await analysisDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); var syntaxNode = root.FindNode(tipInfo.Span); DebugDataTipInfo debugDataTipInfo; if (syntaxNode == null) { debugDataTipInfo = new DebugDataTipInfo(tipInfo.Span, text); } else { debugDataTipInfo = GetInfo(root, semanticModel, syntaxNode, text, cancellationToken); } if (projectionSnapshot != null) { var originalSpan = projectionSnapshot.MapFromSourceSnapshot(new SnapshotSpan(snapshotPoint.Snapshot, debugDataTipInfo.Span.Start, debugDataTipInfo.Span.Length)).FirstOrDefault(); if (originalSpan == default) { return(default);
private static Span MapUpToSnapshot( Span span, ITextSnapshot start, IProjectionSnapshot target ) { var spans = MapUpToSnapshotRecursive(new SnapshotSpan(start, span), target); return(spans.First()); }
/// <remarks> /// This should only be called from within the current language buffer. If there are /// any output or standard input buffers between the specified line and the end of the /// surface buffer, then the result will be incorrect. /// </remarks> private int GetProjectionSpanIndexFromEditableBufferPosition(IProjectionSnapshot surfaceSnapshot, int projectionSpansCount, int surfaceLineNumber) { // The current language buffer is projected to a set of projections interleaved regularly by prompt projections // and ending at the end of the projection buffer, each language buffer projection is on a separate line: // [prompt)[language)...[prompt)[language)<end of projection buffer> int result = projectionSpansCount - (surfaceSnapshot.LineCount - surfaceLineNumber) * SpansPerLineOfInput + 1; Debug.Assert(GetSpanKind(surfaceSnapshot.GetSourceSpan(result)) == ReplSpanKind.Language); return(result); }
internal static SnapshotPoint?MapDownToBufferNoTrack(SnapshotPoint position, ITextBuffer targetBuffer, PositionAffinity affinity) { while (position.Snapshot.TextBuffer != targetBuffer) { IProjectionSnapshot projSnap = position.Snapshot as IProjectionSnapshot; if ((projSnap == null) || (projSnap.SourceSnapshots.Count == 0)) { return(null); } position = projSnap.MapToSourceSnapshot(position, affinity); } return(position); }
internal static SnapshotPoint?MapDownToFirstMatchNoTrack(SnapshotPoint position, Predicate <ITextBuffer> match) { while (!match(position.Snapshot.TextBuffer)) { IProjectionSnapshot projSnap = position.Snapshot as IProjectionSnapshot; if ((projSnap == null) || (projSnap.SourceSnapshots.Count == 0)) { return(null); } position = projSnap.MapToSourceSnapshot(position); } return(position); }
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; } } } }
public SnapshotPoint?MapDownToFirstMatch(SnapshotPoint position, PointTrackingMode trackingMode, Predicate <ITextSnapshot> match, PositionAffinity affinity) { if (position.Snapshot == null) { throw new ArgumentNullException("position"); } if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (match == null) { throw new ArgumentNullException("match"); } if (affinity < PositionAffinity.Predecessor || affinity > PositionAffinity.Successor) { throw new ArgumentOutOfRangeException("affinity"); } if (!this.importingProjectionBufferMap.ContainsKey(position.Snapshot.TextBuffer)) { return(null); } ITextBuffer currentBuffer = position.Snapshot.TextBuffer; ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot; int currentPosition = position.TranslateTo(currentSnapshot, trackingMode).Position; while (!match(currentSnapshot)) { IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase; if (projBuffer == null) { return(null); } IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count == 0) { return(null); } SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition, affinity); currentPosition = currentPoint.Position; currentSnapshot = currentPoint.Snapshot; currentBuffer = currentSnapshot.TextBuffer; } return(new SnapshotPoint(currentSnapshot, currentPosition)); }
/// <summary> /// Initialize a new instance of an <see cref="ElisionSourceSpansChangedEventArgs"/> object. /// </summary> /// <param name="beforeSnapshot">The most recent <see cref="IProjectionSnapshot"/> before the change occurred.</param> /// <param name="afterSnapshot">The <see cref="IProjectionSnapshot"/> immediately after the change occurred.</param> /// <param name="elidedSpans">Zero or more source spans that were hidden.</param> /// <param name="expandedSpans">Zero or more source spans that were expanded.</param> /// <param name="sourceToken">An arbitrary object associated with this change.</param> /// <exception cref="ArgumentNullException">One of <paramref name="beforeSnapshot"/>, <paramref name="afterSnapshot"/>, /// <paramref name="elidedSpans"/>, or <paramref name="expandedSpans"/> is null.</exception> public ElisionSourceSpansChangedEventArgs(IProjectionSnapshot beforeSnapshot, IProjectionSnapshot afterSnapshot, NormalizedSpanCollection elidedSpans, NormalizedSpanCollection expandedSpans, object sourceToken) : base(beforeSnapshot, afterSnapshot, EditOptions.None, sourceToken) { if (elidedSpans == null) { throw new ArgumentNullException("elidedSpans"); } if (expandedSpans == null) { throw new ArgumentNullException("expandedSpans"); } this.elidedSpans = elidedSpans; this.expandedSpans = expandedSpans; }
public SnapshotPoint?MapDownToBuffer(SnapshotPoint position, PointTrackingMode trackingMode, ITextBuffer targetBuffer, PositionAffinity affinity) { if (position.Snapshot == null) { throw new ArgumentNullException("position"); } if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (targetBuffer == null) { throw new ArgumentNullException("targetBuffer"); } if (affinity < PositionAffinity.Predecessor || affinity > PositionAffinity.Successor) { throw new ArgumentOutOfRangeException("affinity"); } ITextBuffer currentBuffer = position.Snapshot.TextBuffer; ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot; int currentPosition = position.TranslateTo(currentSnapshot, trackingMode).Position; while (currentBuffer != targetBuffer) { IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase; if (projBuffer == null) { return(null); } IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count == 0) { return(null); } SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition, affinity); currentPosition = currentPoint.Position; currentSnapshot = currentPoint.Snapshot; currentBuffer = currentSnapshot.TextBuffer; } return(new SnapshotPoint(currentSnapshot, currentPosition)); }
/// <summary> /// Activates a text view for a text buffer, and sets the cursor to a specific location /// </summary> public static bool NavigateToTextBuffer(ITextBuffer textBuffer, int start, int length) { IProjectionSnapshot projectionSnapshot = textBuffer.CurrentSnapshot as IProjectionSnapshot; if (projectionSnapshot != null) { // Find the main buffer for the view SnapshotPoint sourcePoint = new SnapshotPoint(); bool success = true; try { sourcePoint = projectionSnapshot.MapToSourceSnapshot(start, PositionAffinity.Successor); } catch (ArgumentOutOfRangeException) { success = false; } catch (InvalidOperationException) { success = false; } if (success) { return(NavigateToTextBuffer(sourcePoint.Snapshot.TextBuffer, sourcePoint.Position, length)); } } else { // This is the main buffer for the view IVsTextManager textManager = VsAppShell.Current.GetGlobalService <IVsTextManager>(typeof(SVsTextManager)); IVsTextBuffer vsTextBuffer = textBuffer.GetBufferAdapter <IVsTextBuffer>(); Guid viewType = VSConstants.LOGVIEWID_TextView; if (vsTextBuffer != null && ErrorHandler.Succeeded(textManager.NavigateToPosition(vsTextBuffer, ref viewType, start, length))) { return(true); } } return(false); }
/// <summary> /// Initializes a new instance of a <see cref="ProjectionSourceSpansChangedEventArgs"/>. /// </summary> /// <param name="beforeSnapshot">The most recent <see cref="IProjectionSnapshot"/> before the change occurred.</param> /// <param name="afterSnapshot">The <see cref="IProjectionSnapshot"/> immediately after the change occurred.</param> /// <param name="insertedSpans">Zero or more source spans that were inserted into the <see cref="IProjectionBuffer"/>.</param> /// <param name="deletedSpans">Zero or more source spans that were deleted from the <see cref="IProjectionBuffer"/>.</param> /// <param name="spanPosition">The position at which the span changes occurred.</param> /// <param name="options">The edit options that were applied to this change.</param> /// <param name="editTag">An arbitrary object associated with this change.</param> /// <exception cref="ArgumentNullException">One of the parameters: <paramref name="beforeSnapshot"/>, <paramref name="afterSnapshot"/>, /// <paramref name="insertedSpans"/>, or <paramref name="deletedSpans"/>is null.</exception> public ProjectionSourceSpansChangedEventArgs(IProjectionSnapshot beforeSnapshot, IProjectionSnapshot afterSnapshot, IList <ITrackingSpan> insertedSpans, IList <ITrackingSpan> deletedSpans, int spanPosition, EditOptions options, object editTag) : base(beforeSnapshot, afterSnapshot, options, editTag) { if (insertedSpans == null) { throw new ArgumentNullException("insertedSpans"); } if (deletedSpans == null) { throw new ArgumentNullException("deletedSpans"); } this.insertedSpans = new ReadOnlyCollection <ITrackingSpan>(insertedSpans); this.deletedSpans = new ReadOnlyCollection <ITrackingSpan>(deletedSpans); this.spanPosition = spanPosition; }
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 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 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)); } } } }
/// <summary> /// Initializes a new instance of a <see cref="ProjectionSourceBuffersChangedEventArgs"/> object. /// </summary> /// <param name="beforeSnapshot">The most recent <see cref="IProjectionSnapshot"/> before the change occurred.</param> /// <param name="afterSnapshot">The <see cref="IProjectionSnapshot"/> immediately after the change occurred.</param> /// <param name="insertedSpans">Zero or more source spans that were inserted into the <see cref="IProjectionBuffer"/>.</param> /// <param name="deletedSpans">Zero or more source spans that were deleted from the <see cref="IProjectionBuffer"/>.</param> /// <param name="spanPosition">The position in the list of source spans at which the buffer changes occurred.</param> /// <param name="addedBuffers">The list of added source <see cref="ITextBuffer"/> objects.</param> /// <param name="removedBuffers">The list of removed source <see cref="ITextBuffer"/> objects.</param> /// <param name="options">The edit options that were applied to this change.</param> /// <param name="editTag">An arbitrary object associated with this change.</param> /// <exception cref="ArgumentNullException"><paramref name="insertedSpans"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="deletedSpans"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="addedBuffers"/> or <paramref name="removedBuffers"/> is null.</exception> public ProjectionSourceBuffersChangedEventArgs(IProjectionSnapshot beforeSnapshot, IProjectionSnapshot afterSnapshot, IList <ITrackingSpan> insertedSpans, IList <ITrackingSpan> deletedSpans, int spanPosition, IList <ITextBuffer> addedBuffers, IList <ITextBuffer> removedBuffers, EditOptions options, object editTag) : base(beforeSnapshot, afterSnapshot, insertedSpans, deletedSpans, spanPosition, options, editTag) { if (addedBuffers == null) { throw new ArgumentNullException("addedBuffers"); } if (removedBuffers == null) { throw new ArgumentNullException("removedBuffers"); } this.addedBuffers = addedBuffers; this.removedBuffers = removedBuffers; }
public SnapshotPoint?MapDownToInsertionPoint(SnapshotPoint position, PointTrackingMode trackingMode, Predicate <ITextSnapshot> match) { if (position.Snapshot == null) { throw new ArgumentNullException("position"); } if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative) { throw new ArgumentOutOfRangeException("trackingMode"); } if (match == null) { throw new ArgumentNullException("match"); } ITextBuffer currentBuffer = position.Snapshot.TextBuffer; int currentPosition = position.TranslateTo(currentBuffer.CurrentSnapshot, trackingMode); ITextSnapshot currentSnapshot = currentBuffer.CurrentSnapshot; while (!match(currentSnapshot)) { IProjectionBufferBase projBuffer = currentBuffer as IProjectionBufferBase; if (projBuffer == null) { return(null); } IProjectionSnapshot projSnap = projBuffer.CurrentSnapshot; if (projSnap.SourceSnapshots.Count == 0) { return(null); } SnapshotPoint currentPoint = projSnap.MapToSourceSnapshot(currentPosition); currentPosition = currentPoint.Position; currentSnapshot = currentPoint.Snapshot; currentBuffer = currentSnapshot.TextBuffer; } return(new SnapshotPoint(currentSnapshot, currentPosition)); }
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 bool TryGetCurrentLanguageBufferExtent(IProjectionSnapshot projectionSnapshot, out Span result) { if (projectionSnapshot.SpanCount == 0) { result = default(Span); return false; } // the last source snapshot is always a projection of a language buffer: var snapshot = projectionSnapshot.GetSourceSpan(projectionSnapshot.SpanCount - 1).Snapshot; if (snapshot.TextBuffer != CurrentLanguageBuffer) { result = default(Span); return false; } SnapshotPoint start = new SnapshotPoint(snapshot, 0); SnapshotPoint end = new SnapshotPoint(snapshot, snapshot.Length); // projection of the previous version of current language buffer snapshot: var surfaceSpans = projectionSnapshot.MapFromSourceSnapshot(new SnapshotSpan(start, end)); // the language buffer might be projected to multiple surface lines: Debug.Assert(surfaceSpans.Count > 0); result = new Span(surfaceSpans[0].Start, surfaceSpans.Last().End); return true; }
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); } } } }
private static Span MapUpToSnapshot(Span span, ITextSnapshot start, IProjectionSnapshot target) { var spans = MapUpToSnapshotRecursive(new SnapshotSpan(start, span), target); return spans.First(); }
// Do a depth first search through the projection graph to find the first mapping private static IEnumerable<Span> MapUpToSnapshotRecursive(SnapshotSpan start, IProjectionSnapshot target) { foreach (var source in target.SourceSnapshots) { if (source == start.Snapshot) { foreach (var result in target.MapFromSourceSnapshot(start)) { yield return result; } } else if (source is IProjectionSnapshot) { var sourceProjection = source as IProjectionSnapshot; foreach (var span in MapUpToSnapshotRecursive(start, sourceProjection)) { foreach (var result in target.MapFromSourceSnapshot(new SnapshotSpan(source, span))) { yield return result; } } } } yield break; }
private void UpdateSpans(IProjectionSnapshot snapshot) { SpansText = "Spans: " + snapshot.SpanCount.ToString(); }
/// <remarks> /// This should only be called from within the current language buffer. If there are /// any output or standard input buffers between the specified line and the end of the /// surface buffer, then the result will be incorrect. /// </remarks> private int GetProjectionSpanIndexFromEditableBufferPosition(IProjectionSnapshot surfaceSnapshot, int projectionSpansCount, int surfaceLineNumber) { // The current language buffer is projected to a set of projections interleaved regularly by prompt projections // and ending at the end of the projection buffer, each language buffer projection is on a separate line: // [prompt)[language)...[prompt)[language)<end of projection buffer> int result = projectionSpansCount - (surfaceSnapshot.LineCount - surfaceLineNumber) * SpansPerLineOfInput + 1; Debug.Assert(GetSpanKind(surfaceSnapshot.GetSourceSpan(result)) == ReplSpanKind.Input); return result; }
internal static SnapshotSpan GetSourceSpan(this IProjectionSnapshot snapshot, int index) { return(snapshot.GetSourceSpans(index, 1)[0]); }