protected override async Task ProduceTagsAsync(TaggerContext <KeywordHighlightTag> context, DocumentSnapshotSpan documentSnapshotSpan, int?caretPosition) { var cancellationToken = context.CancellationToken; var document = documentSnapshotSpan.Document; if (document == null) { return; } var options = document.Project.Solution.Workspace.Options; if (!options.GetOption(FeatureOnOffOptions.KeywordHighlighting, document.Project.Language)) { return; } if (!caretPosition.HasValue) { return; } var snapshotSpan = documentSnapshotSpan.SnapshotSpan; var position = caretPosition.Value; var snapshot = snapshotSpan.Snapshot; var existingTags = context.GetExistingTags(new SnapshotSpan(snapshot, position, 0)); if (!existingTags.IsEmpty()) { // We already have a tag at this position. So the user is moving from one highlight // tag to another. In this case we don't want to recompute anything. Let our caller // know that we should preserve all tags. context.SetSpansTagged(SpecializedCollections.EmptyEnumerable <DocumentSnapshotSpan>()); return; } using (Logger.LogBlock(FunctionId.Tagger_Highlighter_TagProducer_ProduceTags, cancellationToken)) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var spans = _highlightingService.GetHighlights(root, position, cancellationToken); foreach (var span in spans) { context.AddTag(new TagSpan <KeywordHighlightTag>(span.ToSnapshotSpan(snapshot), KeywordHighlightTag.Instance)); } } }
protected override Task ProduceTagsAsync(TaggerContext <NavigableHighlightTag> context) { // NOTE(cyrusn): Normally we'd limit ourselves to producing tags in the span we were // asked about. However, we want to produce all tags here so that the user can actually // navigate between all of them using the appropriate tag navigation commands. If we // don't generate all the tags then the user will cycle through an incorrect subset. if (context.CaretPosition == null) { return(SpecializedTasks.EmptyTask); } var caretPosition = context.CaretPosition.Value; Workspace workspace; if (!Workspace.TryGetWorkspace(caretPosition.Snapshot.AsText().Container, out workspace)) { return(SpecializedTasks.EmptyTask); } var document = context.SpansToTag.First(vt => vt.SnapshotSpan.Snapshot == caretPosition.Snapshot).Document; if (document == null) { return(SpecializedTasks.EmptyTask); } // Don't produce tags if the feature is not enabled. if (!workspace.Options.GetOption(FeatureOnOffOptions.ReferenceHighlighting, document.Project.Language)) { return(SpecializedTasks.EmptyTask); } var existingTags = context.GetExistingTags(new SnapshotSpan(caretPosition, 0)); if (!existingTags.IsEmpty()) { // We already have a tag at this position. So the user is moving from one highlight // tag to another. In this case we don't want to recompute anything. Let our caller // know that we should preserve all tags. context.SetSpansTagged(SpecializedCollections.EmptyEnumerable <DocumentSnapshotSpan>()); return(SpecializedTasks.EmptyTask); } // Otherwise, we need to go produce all tags. return(ProduceTagsAsync(context, caretPosition, workspace, document)); }