IAsynchronousTaggerDataSource.cs 6.1 KB
Newer Older
1 2
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

3
using System;
4
using System.Collections.Generic;
5 6
using System.Threading;
using System.Threading.Tasks;
7
using Microsoft.CodeAnalysis.Editor.Shared.Tagging;
8
using Microsoft.CodeAnalysis.Options;
9 10 11 12 13 14
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;

namespace Microsoft.CodeAnalysis.Editor.Tagging
{
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    /// <summary>
    /// Flags that affect how the tagger infrastructure responds to caret changes.
    /// </summary>
    [Flags]
    internal enum TaggerCaretChangeBehavior
    {
        /// <summary>
        /// No special caret change behavior.
        /// </summary>
        None = 0,

        /// <summary>
        /// If the caret moves outside of a tag, immediately remove all existing tags.
        /// </summary>
        RemoveAllTagsOnCaretMoveOutsideOfTag = 1 << 0,
    }

32
    /// <summary>
33 34
    /// Data source for the <see cref="AsynchronousTaggerProvider{TTag, TState}"/>.  This type tells the
    /// <see cref="AsynchronousTaggerProvider{TTag, TState}"/> when tags need to be recomputed, as well
35 36
    /// as producing the tags when requested.
    /// </summary>
37
    internal interface IAsynchronousTaggerDataSource<TTag, TState> where TTag : ITag
38 39
    {
        /// <summary>
40 41 42 43
        /// The behavior the tagger engine will have when text changes happen to the subject buffer
        /// it is attached to.  Most taggers can simply use <see cref="TaggerTextChangeBehavior.None"/>.
        /// However, advanced taggers that want to perform specialized behavior depending on what has
        /// actually changed in the file can specify <see cref="TaggerTextChangeBehavior.TrackTextChanges"/>.
44
        /// 
45 46 47
        /// If this is specified the tagger engine will track text changes and pass them along as
        /// <see cref="AsynchronousTaggerContext{TTag, TState}.TextChangeRange"/> when calling 
        /// <see cref="ProduceTagsAsync"/>.
48
        /// </summary>
49
        TaggerTextChangeBehavior TextChangeBehavior { get; }
50

51 52 53 54 55
        /// <summary>
        /// The bahavior the tagger will have when changes happen to the caret.
        /// </summary>
        TaggerCaretChangeBehavior CaretChangeBehavior { get; }

56 57 58 59 60 61 62
        /// <summary>
        /// The behavior of tags that are created by the async tagger.  This will matter for tags
        /// created for a previous version of a document that are mapped forward by the async
        /// tagging architecture.  This value cannot be <see cref="SpanTrackingMode.Custom"/>.
        /// </summary>
        SpanTrackingMode SpanTrackingMode { get; }

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
        /// <summary>
        /// Whether or not the the first set of tags for this tagger should be computed synchronously.
        /// </summary>
        bool ComputeTagsSynchronouslyIfNoAsynchronousComputationHasCompleted { get; }

        /// <summary>
        /// Options controlling this tagger.  The tagger infrastructure will check this option
        /// against the buffer it is associated with to see if it should tag or not.
        /// 
        /// An empty enumerable, or null, can be returned to indicate that this tagger should 
        /// run unconditionally.
        /// </summary>
        IEnumerable<Option<bool>> Options { get; }

        IEnumerable<PerLanguageOption<bool>> PerLanguageOptions { get; }

79 80
        /// <summary>
        /// Comparer used to determine if two <see cref="ITag"/>s are the same.  This is used by
81
        /// the <see cref="AsynchronousTaggerProvider{TTag, TState}"/> to determine if a previous set of
82 83 84 85 86 87 88 89
        /// computed tags and a current set of computed tags should be considered the same or not.
        /// If they are the same, then the UI will not be updated.  If they are different then
        /// the UI will be updated for sets of tags that have been removed or added.
        /// </summary>
        /// <returns></returns>
        IEqualityComparer<TTag> TagComparer { get; }

        /// <summary>
90
        /// Creates the <see cref="ITaggerEventSource"/> that notifies the <see cref="AsynchronousTaggerProvider{TTag, TState}"/>
91 92 93 94
        /// that it should recompute tags for the text buffer after an appropriate <see cref="TaggerDelay"/>.
        /// </summary>
        ITaggerEventSource CreateEventSource(ITextView textViewOpt, ITextBuffer subjectBuffer);

95 96 97 98 99 100 101 102 103 104 105
        /// <summary>
        /// Called by the <see cref="AsynchronousTaggerProvider{TTag, TState}"/> infrastructure to 
        /// determine the caret position.  This value will be passed in as the value to 
        /// <see cref="AsynchronousTaggerContext{TTag, TState}.CaretPosition"/> in the call to
        /// <see cref="ProduceTagsAsync"/>.
        /// 
        /// Return <code>null</code> to get the default tagger behavior.  This will the caret
        /// position in the subject buffer this tagger is attached to.
        /// </summary>
        SnapshotPoint? GetCaretPoint(ITextView textViewOpt, ITextBuffer subjectBuffer);

106
        /// <summary>
107
        /// Called by the <see cref="AsynchronousTaggerProvider{TTag, TState}"/> infrastructure to determine
108 109 110 111
        /// the set of spans that it should asynchronously tag.  This will be called in response to
        /// notifications from the <see cref="ITaggerEventSource"/> that something has changed, and
        /// will only be called from the UI thread.  The tagger infrastructure will then determine
        /// the <see cref="DocumentSnapshotSpan"/>s associated with these <see cref="SnapshotSpan"/>s
112
        /// and will asycnhronously call into <see cref="ProduceTagsAsync"/> at some point in
113 114 115 116 117 118
        /// the future to produce tags for these spans.
        /// 
        /// Return <code>null</code> to get the default set of spans tagged.  This will normally be 
        /// the span of the entire text buffer.
        /// </summary>
        IEnumerable<SnapshotSpan> GetSpansToTag(ITextView textViewOpt, ITextBuffer subjectBuffer);
119 120

        /// <summary>
121
        /// Produce tags for the given context.
122
        /// </summary>
123
        Task ProduceTagsAsync(AsynchronousTaggerContext<TTag,TState> context);
124
    }
125
}