public IEnumerable <ITagSpan <MutationCodeHighlightTag> > GetTags(NormalizedSnapshotSpanCollection spans) { try { var tags = new List <ITagSpan <MutationCodeHighlightTag> >(); var currentSnapshot = SourceBuffer.CurrentSnapshot; foreach (var trackingSpan in _trackingSpans.Keys) { var spanInCurrentSnapshot = trackingSpan.GetSpan(currentSnapshot); if (spans.Any(sp => spanInCurrentSnapshot.IntersectsWith(sp))) { var snapshotSpan = new SnapshotSpan(currentSnapshot, spanInCurrentSnapshot); var mutation = _mutations.FirstOrDefault(m => m.Mutation.Document.Id == _trackingSpans[trackingSpan]); if (mutation == null) { continue; } tags.Add(new TagSpan <MutationCodeHighlightTag>(snapshotSpan, new MutationCodeHighlightTag(_mutationDefinitions[mutation.Mutation.Status], mutation))); } } return(tags); } catch (Exception) { return(new List <ITagSpan <MutationCodeHighlightTag> >()); } }
// Produces tags on the snapshot that the tag consumer asked for. public IEnumerable <ITagSpan <IntraTextAdornmentTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans == null || !spans.Any()) { yield break; } // Translate the request to the snapshot that this tagger is current with. var requestedSnapshot = spans[0].Snapshot; var translatedSpans = new NormalizedSnapshotSpanCollection( spans.Select(span => span.TranslateTo(snapshot, SpanTrackingMode.EdgeExclusive))); // Grab the adornments. foreach (var tagSpan in GetAdornmentTagsOnSnapshot(translatedSpans)) { // Make sure text is not empty, and that it's more than an empty comment if (string.IsNullOrWhiteSpace(tagSpan.Span.GetText())) { continue; } // Translate each adornment to the snapshot that the tagger was asked about. var span = tagSpan.Span.TranslateTo(requestedSnapshot, SpanTrackingMode.EdgeExclusive); var tag = new IntraTextAdornmentTag(tagSpan.Tag.Adornment, tagSpan.Tag.RemovalCallback, tagSpan.Tag.Affinity); yield return(new TagSpan <IntraTextAdornmentTag>(span, tag)); } }
private static bool IntersectionExists(Span span, NormalizedSnapshotSpanCollection spans) => // We're using "IntersectsWith" rather than "OverlapsWith" so that zero-length spans are handled correctly. // Given two spans A = [10 -> 15] and B = [12 -> 12], // * A.IntersectsWith(B) == true // * A.OverlapsWith(B) == false. // This matters because when VS is requesting tags to show tooltips it uses a zero-length span. spans.Any(x => x.IntersectsWith(span));
public IEnumerable <ITagSpan <TextMarkerTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (_highlightedSpans?.Any() ?? false) { if (spans.First().Snapshot != _highlightedSpans.First().Snapshot) { _highlightedSpans = new NormalizedSnapshotSpanCollection( from span in _highlightedSpans select span.TranslateTo(spans.First().Snapshot, SpanTrackingMode.EdgeExclusive) ); } foreach (var span in NormalizedSnapshotSpanCollection.Overlap(spans, _highlightedSpans)) { yield return(new TagSpan <FrameNameReferenceTag>(span, FrameNameReferenceTag.Instance)); } } if (_definitionSpans?.Any() ?? false) { if (spans.First().Snapshot != _definitionSpans.First().Snapshot) { _definitionSpans = new NormalizedSnapshotSpanCollection( from span in _definitionSpans select span.TranslateTo(spans.First().Snapshot, SpanTrackingMode.EdgeExclusive) ); } foreach (var span in NormalizedSnapshotSpanCollection.Overlap(spans, _definitionSpans)) { yield return(new TagSpan <FrameNameDefinitionTag>(span, FrameNameDefinitionTag.Instance)); } } }
/// <summary> /// Метод получения тегов. /// </summary> /// <param name="spans">Нормализованная коллекция спанов.</param> /// <returns>Список тегов с ошибками.</returns> public IEnumerable <ITagSpan <SpellErrorTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (classifier == null || spans == null || !spans.Any()) { yield break; } lock (spellErrorsLock) { if (!spellErrors.Any()) { yield break; } var snapshot = buffer.CurrentSnapshot; foreach (var spellError in spellErrors) { var tagSpan = spellError.GetTagSpan(snapshot); if (tagSpan.Span.Length == 0) { continue; } if (spans.IntersectsWith(new NormalizedSnapshotSpanCollection(tagSpan.Span))) { yield return(tagSpan); } } } }
public IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (!spans.Any()) { yield break; } var artifacts = artifactsGetter(); // Start from the first artifact after the start // position. Since code blocks will always have // an end-boundary artifact, this will work even // if we start in the middle of a code block. int i = artifacts.GetFirstItemAfterOrAtPosition(spans[0].Start); if (i < 0) { yield break; } CodeBlockInfo lastBlock = null; for (; i < artifacts.Count; i++) { var cba = artifacts[i] as ICodeBlockArtifact; // Skip artifacts that aren't in code blocks, and // those in code blocks we have already returned. if (cba == null || cba.BlockInfo == lastBlock) { continue; } lastBlock = cba.BlockInfo; // Skip single-line indented code blocks, but not single-line fenced code blocks if (lastBlock.CodeLines.Count == 1 && lastBlock.OuterEnd.End == lastBlock.CodeLines[0].End) { continue; } yield return(new TagSpan <IOutliningRegionTag>( new SnapshotSpan(spans[0].Snapshot, Span.FromBounds(lastBlock.OuterStart.Start, lastBlock.OuterEnd.End)), tagCreator( Caption(lastBlock), lastBlock.CodeLines .Select(a => a.InnerRange.ToSnapshotSpan(spans[0].Snapshot)) .ToList() // Force eager evaluation; this query is only enumerated when a tooltip is shown, so we need to grab the snapshot ) )); if (lastBlock.OuterStart.Start > spans.Last().End) { break; // If we have completely passed the requested range, stop. } } }
public IEnumerable <ITagSpan <GherkinTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans) { var tags = new List <ITagSpan <GherkinTokenTag> >(); if (spans.Any()) { var events = tokenParser.Events; tags.AddRange(spans.SelectMany(_ => gherkinStepTagger.CreateTags(events, _))); } return(tags); }
public IEnumerable <ITagSpan <TextMarkerTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (!_textView.Properties.TryGetProperty(PropertyName, out List <Span> allSpans)) { return(null); } return(allSpans .Where(s => spans.Any(ss => ss.IntersectsWith(s))) .Select(s => new TagSpan <TextMarkerTag>(new SnapshotSpan(spans.First().Snapshot, s), ProjectionSpanTag.Instance))); }
public static SnapshotSpan?MapUpOrDownToFirstMatch(this IBufferGraph bufferGraph, SnapshotSpan span, Predicate <ITextSnapshot> match) { NormalizedSnapshotSpanCollection spans = bufferGraph.MapDownToFirstMatch(span, SpanTrackingMode.EdgeExclusive, match); if (!spans.Any()) { spans = bufferGraph.MapUpToFirstMatch(span, SpanTrackingMode.EdgeExclusive, match); } return(spans.Select(s => new SnapshotSpan?(s)) .FirstOrDefault()); }
private IEnumerable <TagSpan <TTag> > GetAdornmentTagsOnSnapshot(NormalizedSnapshotSpanCollection spans) { ITextSnapshot snapshot = spans[0].Snapshot; string spanText = snapshot.GetText(); int lastOpen = spanText.IndexOf($"<{_tagName}", StringComparison.Ordinal); while (lastOpen > -1) { int include = spanText.IndexOf("Include", lastOpen, StringComparison.Ordinal); if (include > -1) { int quote = spanText.IndexOf('"', lastOpen); if (quote > -1) { SnapshotSpan s = new SnapshotSpan(snapshot, new Span(quote + 1, 1)); KeyValuePair <SnapshotSpan, TTag> existingTag = _map.FirstOrDefault(x => x.Key.TranslateTo(snapshot, SpanTrackingMode.EdgeInclusive).IntersectsWith(s)); if (_factory.TryCreateOrUpdate(_textView, s, existingTag.Value, out TagSpan <TTag> targetTag, out Span valueSpan)) { if (existingTag.Key != null) { if (!existingTag.Key.Equals(targetTag.Span)) { _map.Remove(existingTag.Key); _map[targetTag.Span] = targetTag.Tag; } } else { _map[targetTag.Span] = targetTag.Tag; } if (spans.Any(x => x.OverlapsWith(valueSpan))) { targetTag.Tag.UpdateLayout(); yield return(targetTag); } } } } if (lastOpen + 1 >= spanText.Length) { break; } lastOpen = spanText.IndexOf($"<{_tagName}", lastOpen + 1, StringComparison.Ordinal); } }
private static void DebugVerifyTags(NormalizedSnapshotSpanCollection requestedSpans, IEnumerable <ITagSpan <TTag> > tags) { if (tags == null) { return; } foreach (var tag in tags) { var span = tag.Span; if (!requestedSpans.Any(s => s.IntersectsWith(span))) { Contract.Fail(tag + " doesn't intersects with any requested span"); } } }
private void UpdateAtCaretPosition(CaretPosition caretPosition) { SnapshotPoint?point = caretPosition.Point.GetPoint(SourceBuffer, caretPosition.Affinity); if (point == null) { return; } if (_highlightedSpans?.FirstOrDefault().Snapshot == SourceBuffer.CurrentSnapshot && (_highlightedSpans?.Any(s => s.Contains(point.Value)) ?? false)) { return; } NormalizedSnapshotSpanCollection newHighlightedSpans = null; this.HtmlDocument.HtmlEditorTree.GetPositionElement(point.Value.Position, out _, out AttributeNode attribute); if ((attribute?.ValueRangeUnquoted.Contains(point.Value.Position) ?? false) || (attribute?.ValueRangeUnquoted.End == point.Value.Position)) { if (attribute.Name?.Equals("class", StringComparison.InvariantCultureIgnoreCase) ?? false) { int relativeIndex = point.Value.Position - attribute.ValueRangeUnquoted.Start; // find definitions string @class = ClassRegex.Matches(attribute.Value) .Cast <Match>() .FirstOrDefault(m => m.Index <= relativeIndex && relativeIndex <= m.Index + m.Length)? .Value; // find references if (@class != null) { newHighlightedSpans = new NormalizedSnapshotSpanCollection(FindReferences(@class, point.Value.Snapshot)); } } } _highlightedSpans = newHighlightedSpans; TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(SourceBuffer.CurrentSnapshot, 0, SourceBuffer.CurrentSnapshot.Length))); }
private void WordSelectDeferrer_Idle(object sender, BackgroundDeferrer.IdleEventArgs e) { ThreadHelper.JoinableTaskFactory.RunAsync(async() => { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var snapPt = (SnapshotPoint)e.Value; if (_sourceBuffer.CurrentSnapshot != snapPt.Snapshot) { Update(snapPt, null); return; } var snapshot = snapPt.Snapshot; var fileStore = CodeModel.FileStore.GetOrCreateForTextBuffer(_sourceBuffer); if (fileStore != null) { var appSettings = ProbeEnvironment.CurrentAppSettings; var fileName = VsTextUtil.TryGetDocumentFileName(_sourceBuffer); var model = fileStore.GetCurrentModel(appSettings, fileName, _sourceBuffer.CurrentSnapshot, "Word select idle"); var modelPos = model.AdjustPosition(snapPt); var caretToken = model.File.FindDownwardTouching(modelPos).LastOrDefault(t => t.SourceDefinition != null); if (caretToken == null) { Update(snapPt, null); return; } var sourceDef = caretToken.SourceDefinition; var file = model.File; var matchingTokens = file.FindDownward(t => t.SourceDefinition == sourceDef); var wordSpans = new NormalizedSnapshotSpanCollection(from t in matchingTokens select new SnapshotSpan(snapshot, VsTextUtil.ModelSpanToVsSnapshotSpan(model.Snapshot, t.Span, snapshot))); if (!wordSpans.Any()) { wordSpans = null; } Update(snapPt, wordSpans); } }); }
public IEnumerable <ITagSpan <IErrorTag> > GetTags(NormalizedSnapshotSpanCollection spans) { var tags = new List <ITagSpan <IErrorTag> >(); if (_document.IsParsing || _validator.IsValidating || !_hasLoaded || !spans.Any() || spans[0].IsEmpty) { return(tags); } ITextSnapshotLine line = spans[0].Start.GetContainingLine(); IEnumerable <ParseItem> items = _document.ItemsInSpan(line.Extent); foreach (ParseItem item in items) { tags.AddRange(CreateError(item)); } return(tags); }
public IEnumerable <ITagSpan <ScoreGlyphTag> > GetTags(NormalizedSnapshotSpanCollection spans) { RemoveEmptyTrackingSpans(); List <ITagSpan <ScoreGlyphTag> > res = new List <ITagSpan <ScoreGlyphTag> >(); var currentSnapshot = _buffer.CurrentSnapshot; foreach (KeyValuePair <ITrackingSpan, CompileValue> item in _trackingSpans) { var spanInCurrentSnapshot = item.Key.GetSpan(currentSnapshot); if (spans.Any(sp => spanInCurrentSnapshot.IntersectsWith(sp))) { var snapshotSpan = new SnapshotSpan(currentSnapshot, spanInCurrentSnapshot); res.Add(new TagSpan <ScoreGlyphTag>(snapshotSpan, new ScoreGlyphTag(item.Value))); } } return(res); }
public IEnumerable <ITagSpan <PlayGlyphTag> > GetTags(NormalizedSnapshotSpanCollection spans) { var textSnapshot = (spans.Any()) ? spans.First().Snapshot : null; if (!features.Any() && textSnapshot != null && !tokenParser.LastParseFailed()) { tokenParser.ForceParse(textSnapshot); } var tagSPans = new List <ITagSpan <PlayGlyphTag> >(); foreach (var line in textSnapshot.Lines) { var spanLine = line.LineNumber + 1; AddFeatureTagSpan(spanLine, textSnapshot, line, tagSPans); AddScenarioTagSpan(spanLine, textSnapshot, line, tagSPans); } return(tagSPans); }
public IEnumerable <ITagSpan <HighlightWordTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0 || !highlightedSpans.Any()) { yield break; } var highSpans = this.highlightedSpans; if (highSpans[0].Snapshot != spans[0].Snapshot) { highSpans = new NormalizedSnapshotSpanCollection(highSpans.Select(s => s.TranslateTo(spans[0].Snapshot, SpanTrackingMode.EdgeExclusive))); } foreach (SnapshotSpan span in NormalizedSnapshotSpanCollection.Overlap(spans, highSpans)) { yield return(new TagSpan <HighlightWordTag>(span, new HighlightWordTag())); } }
/// <summary> /// Получение тегов. /// </summary> /// <param name="spans">Набор спанов.</param> /// <returns>Перечисление тегов.</returns> public IEnumerable <ITagSpan <MisspellingSmartTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (!spans.Any()) { yield break; } var snapshot = buffer.CurrentSnapshot; foreach (var misspelling in misspellingAggregator.GetTags(spans)) { var misspellingSpans = misspelling.Span.GetSpans(snapshot); if (misspellingSpans.Count != 1) { continue; } var errorSpan = misspellingSpans[0]; var smartTagActions = GetSmartTagActions(errorSpan, misspelling.Tag.Suggestions); yield return(new TagSpan <MisspellingSmartTag>(errorSpan, new MisspellingSmartTag(smartTagActions))); } }
public IEnumerable <ITagSpan <DocumentationTag> > GetTags(NormalizedSnapshotSpanCollection spans) { List <ITagSpan <DocumentationTag> > tags = new List <ITagSpan <DocumentationTag> >(); if (spans.Count == 0) { return(tags); } var relevantSnapshot = spans.First().Snapshot;//_buffer.CurrentSnapshot; foreach (var trackingSpan in _trackingSpans.Keys) { var spanInCurrentSnapshot = trackingSpan.GetSpan(relevantSnapshot); if (spans.Any(sp => spanInCurrentSnapshot.IntersectsWith(sp))) { var snapshotSpan = new SnapshotSpan(relevantSnapshot, spanInCurrentSnapshot); var documentationText = _trackingSpans[trackingSpan]; tags.Add(new TagSpan <DocumentationTag>(snapshotSpan, new DocumentationTag(documentationText, trackingSpan, _buffer))); } } return(tags); }
public static void CommentSelection( ITextBuffer textBuffer, IEnumerable <VirtualSnapshotSpan> selectedSpans, XDocument xmlDocumentSyntax, IEditorOperations editorOperations = null, IMultiSelectionBroker multiSelectionBroker = null) { var snapshot = textBuffer.CurrentSnapshot; var spansToExpandIntoComments = new List <SnapshotSpan> (); var newCommentInsertionPoints = new List <VirtualSnapshotPoint> (); foreach (var selectedSpan in selectedSpans) { // empty selection on an empty line results in inserting a new comment if (selectedSpan.IsEmpty && string.IsNullOrWhiteSpace(snapshot.GetLineFromPosition(selectedSpan.Start.Position).GetText())) { newCommentInsertionPoints.Add(selectedSpan.Start); } else { spansToExpandIntoComments.Add(selectedSpan.SnapshotSpan); } } NormalizedSnapshotSpanCollection commentSpans = NormalizedSnapshotSpanCollection.Empty; if (spansToExpandIntoComments.Any()) { commentSpans = GetCommentableSpansInSelection(xmlDocumentSyntax, spansToExpandIntoComments); } using (var edit = textBuffer.CreateEdit()) { if (commentSpans.Any()) { CommentSpans(edit, commentSpans); } if (newCommentInsertionPoints.Any()) { CommentEmptySpans(edit, newCommentInsertionPoints, editorOperations); } edit.Apply(); } var newSnapshot = textBuffer.CurrentSnapshot; // Now fix up the selections after the edit. var translatedInsertionPoints = newCommentInsertionPoints.Select(p => p.TranslateTo(newSnapshot)).ToHashSet(); var fixupSelectionStarts = selectedSpans.Where(s => !s.IsEmpty).ToDictionary( c => c.Start.TranslateTo(newSnapshot, PointTrackingMode.Positive), c => c.Start.TranslateTo(newSnapshot, PointTrackingMode.Negative)); if (multiSelectionBroker != null) { multiSelectionBroker.PerformActionOnAllSelections(transformer => { // for newly inserted comments position the caret inside the comment if (translatedInsertionPoints.Contains(transformer.Selection.ActivePoint)) { transformer.MoveTo( new VirtualSnapshotPoint(transformer.Selection.End.Position - CloseComment.Length), select: false, insertionPointAffinity: PositionAffinity.Successor); // for commented code make sure the new selection includes the opening <!-- } else if (fixupSelectionStarts.TryGetValue(transformer.Selection.Start, out var newStart)) { var end = transformer.Selection.End; transformer.MoveTo(newStart, select: false, PositionAffinity.Successor); transformer.MoveTo(end, select: true, PositionAffinity.Successor); } }); } }
private bool CaretIntersectsSingleErrorLocation(LocationModel locationModel, NormalizedSnapshotSpanCollection caretSpanCollection) => caretSpanCollection.Any( caretSpan => locationModel.PersistentSpan != null && caretSpan.IntersectsWith(locationModel.PersistentSpan.Span.GetSpan(caretSpan.Snapshot)));