public StructureTag( AbstractStructureTaggerProvider tagProvider, BlockSpan blockSpan, ITextSnapshot snapshot ) { Snapshot = snapshot; OutliningSpan = blockSpan.TextSpan.ToSpan(); Type = ConvertType(blockSpan.Type); IsCollapsible = blockSpan.IsCollapsible; IsDefaultCollapsed = blockSpan.IsDefaultCollapsed; IsImplementation = blockSpan.AutoCollapse; if (blockSpan.HintSpan.Start < blockSpan.TextSpan.Start) { // The HeaderSpan is what is used for drawing the guidelines and also what is shown if // you mouse over a guideline. We will use the text from the hint start to the collapsing // start; in the case this spans mutiple lines the editor will clip it for us and suffix an // ellipsis at the end. HeaderSpan = Span.FromBounds(blockSpan.HintSpan.Start, blockSpan.TextSpan.Start); } else { var hintLine = snapshot.GetLineFromPosition(blockSpan.HintSpan.Start); HeaderSpan = AbstractStructureTaggerProvider.TrimLeadingWhitespace(hintLine.Extent); } CollapsedText = blockSpan.BannerText; CollapsedHintFormSpan = blockSpan.HintSpan.ToSpan(); _tagProvider = tagProvider; }
protected sealed override async Task ProduceTagsAsync( TaggerContext <TRegionTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { try { // Let LSP handle producing tags in the cloud scenario if (documentSnapshotSpan.Document.IsInCloudEnvironmentClientContext()) { return; } var outliningService = AbstractStructureTaggerProvider <TRegionTag> .TryGetService(context, documentSnapshotSpan); if (outliningService != null) { var blockStructure = await outliningService.GetBlockStructureAsync( documentSnapshotSpan.Document, context.CancellationToken).ConfigureAwait(false); ProcessSpans( context, documentSnapshotSpan.SnapshotSpan, outliningService, blockStructure.Spans); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
protected sealed override void ProduceTagsSynchronously( TaggerContext <TRegionTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { try { // Let LSP handle producing tags in the cloud scenario if (documentSnapshotSpan.Document.IsInCloudEnvironmentClientContext()) { return; } var outliningService = AbstractStructureTaggerProvider <TRegionTag> .TryGetService(context, documentSnapshotSpan); if (outliningService != null) { var document = documentSnapshotSpan.Document; var cancellationToken = context.CancellationToken; // Try to call through the synchronous service if possible. Otherwise, fallback // and make a blocking call against the async service. var blockStructure = outliningService.GetBlockStructure(document, cancellationToken); ProcessSpans( context, documentSnapshotSpan.SnapshotSpan, outliningService, blockStructure.Spans); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
public RegionTag( AbstractStructureTaggerProvider <TRegionTag> provider, ITextSnapshot snapshot, BlockSpan outliningSpan) { _provider = provider; _subjectBuffer = snapshot.TextBuffer; BlockSpan = outliningSpan; _hintSpan = snapshot.CreateTrackingSpan(BlockSpan.HintSpan.ToSpan(), SpanTrackingMode.EdgeExclusive); }
private void ProcessSpansWorker( TaggerContext <TRegionTag> context, SnapshotSpan snapshotSpan, BlockStructureService outliningService, ImmutableArray <BlockSpan> spans) { if (spans != null) { var snapshot = snapshotSpan.Snapshot; spans = AbstractStructureTaggerProvider <TRegionTag> .GetMultiLineRegions(outliningService, spans, snapshot); // Create the outlining tags. var tagSpanStack = new Stack <TagSpan <TRegionTag> >(); foreach (var region in spans) { var spanToCollapse = new SnapshotSpan(snapshot, region.TextSpan.ToSpan()); while (tagSpanStack.Count > 0 && tagSpanStack.Peek().Span.End <= spanToCollapse.Span.Start) { tagSpanStack.Pop(); } var parentTag = tagSpanStack.Count > 0 ? tagSpanStack.Peek() : null; var tag = CreateTag(parentTag?.Tag, snapshot, region); if (tag != null) { var tagSpan = new TagSpan <TRegionTag>(spanToCollapse, tag); context.AddTag(tagSpan); tagSpanStack.Push(tagSpan); } } } }