To be precise, the squiggle adornment has a Brush that is either a Red SolidColorBrush or is a brush that is determined by the exported EditorFormatDefinition with NameAttribute name matching that of the IErrorTag.ErrorType with a corresponding exported ErrorTypeDefinition that too has a NameAttribute matching the IErrorTag.ErrorType.
It is the ResourceDictionary from EditorFormatDefinition.CreateResourceDictionaryFromDefinition that determines the Brush. If you are not overriding this method then your exported EditorFormatDefinition can set either ForegroundColor for a SolidColorBrush or set ForegroundBrush to any Brush implementation.
These exports can be on the ITagger<T>
implementation.
For instance
class ErrorEditorFormatDefinition : EditorFormatDefinition
{
public ErrorEditorFormatDefinition(Color errorColor, string displayName = null) : this(displayName)
{
this.ForegroundColor = errorColor;
}
public ErrorEditorFormatDefinition(Brush brush, string displayName = null) : this(displayName)
{
this.ForegroundBrush = brush;
}
private ErrorEditorFormatDefinition(string displayName)
{
if (displayName != null)
{
this.DisplayName = displayName;
}
this.BackgroundCustomizable = false;
}
}
internal class ErrorTagger : ITagger<IErrorTag>
{
public const string MethodNotCoveredErrorType = "MethodNotCovered";
public const string MethodPartiallyCoveredErrorType = "MethodPartiallyCovered";
public const string LineNotCoveredErrorType = "LineNotCovered";
public const string LinePartiallyCoveredErrorType = "LinePartiallyCovered";
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
[Export(typeof(ErrorTypeDefinition))]
[Name(MethodNotCoveredErrorType)]
public ErrorTypeDefinition MethodNotCoveredErrorTypeDefinition { get; }
[Export(typeof(ErrorTypeDefinition))]
[Name(MethodPartiallyCoveredErrorType)]
public ErrorTypeDefinition MethodPartiallyErrorTypeDefinition { get; }
[Export(typeof(ErrorTypeDefinition))]
[Name(LineNotCoveredErrorType)]
public ErrorTypeDefinition LineNotCoveredErrorTypeDefinition { get; }
[Export(typeof(ErrorTypeDefinition))]
[Name(LinePartiallyCoveredErrorType)]
public ErrorTypeDefinition LinePartiallyErrorTypeDefinition { get; }
[Export(typeof(EditorFormatDefinition))]
[Name(MethodNotCoveredErrorType)]
[UserVisible(true)]
public EditorFormatDefinition MethodNotCoveredErrorFormatDefinition { get; } = new ErrorEditorFormatDefinition(new SolidColorBrush(Colors.Pink));
[Export(typeof(EditorFormatDefinition))]
[Name(MethodPartiallyCoveredErrorType)]
public EditorFormatDefinition MethodPartiallyCoveredErrorFormatDefinition { get; } = new ErrorEditorFormatDefinition(new LinearGradientBrush()
{
StartPoint = new System.Windows.Point(0, 0),
EndPoint = new System.Windows.Point(1, 0),
GradientStops = new GradientStopCollection
{
new GradientStop(Colors.Yellow, 0.0),
new GradientStop(Colors.Red, 0.25),
new GradientStop(Colors.Blue, 0.75),
new GradientStop(Colors.LimeGreen, 1.0)
}
},"Call me what you want");
[Name(LineNotCoveredErrorType)]
[Export(typeof(EditorFormatDefinition))]
public EditorFormatDefinition LineNotCoveredErrorFormatDefinition { get; } = new ErrorEditorFormatDefinition(Colors.Brown);
[Name(LinePartiallyCoveredErrorType)]
public EditorFormatDefinition LinePartiallyCoveredErrorFormatDefinition { get; } = new ErrorEditorFormatDefinition(Colors.Cyan);
public IEnumerable<ITagSpan<IErrorTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
return new List<ITagSpan<IErrorTag>>
{
// determine as appropriate
new TagSpan<IErrorTag>(new SnapshotSpan(spans[0].Snapshot, new Span(0, spans[0].Snapshot.Length)), new ErrorTag(MethodPartiallyCoveredErrorType, "Method partially covered")),
};
}
}
The PredefinedErrorTypeNames are just those that are guaranteed to have a matching ErrorTypeDefinition/EditorFormatDefinition.
public static class PredefinedErrorTypeNames {
/// <summary>Represents syntax errors.</summary>
public const string SyntaxError = "syntax error";
/// <summary>Represents compiler errors.</summary>
public const string CompilerError = "compiler error";
/// <summary>Represents other errors.</summary>
public const string OtherError = "other error";
/// <summary>Represents compiler warnings.</summary>
public const string Warning = "compiler warning";
/// <summary>Represents a suggestion with no visual treatment.</summary>
public const string Suggestion = "suggestion";
///<summary>Represents a suggestion with subtle visual treatment.</summary>
public const string HintedSuggestion = "hinted suggestion";
}
Note that Suggestion is not visible in Fonts And Colors - also check the DisplayName changes below for how to find these in Fonts And Colors.
[Export(typeof(EditorFormatDefinition))]
[Name("suggestion")]
[UserVisible(false)]
internal class SuggestionClassificationFormatDefinition : EditorFormatDefinition
{
public SuggestionClassificationFormatDefinition()
{
this.ForegroundBrush = (Brush)Brushes.Transparent;
this.BackgroundCustomizable = new bool?(false);
this.DisplayName = "Suggestion";
}
}
[Export(typeof(EditorFormatDefinition))]
[Name("compiler warning")]
[UserVisible(true)]
internal class WarningClassificationFormatDefinition : EditorFormatDefinition
{
public WarningClassificationFormatDefinition()
{
this.ForegroundBrush = (Brush)new SolidColorBrush(Color.FromRgb((byte)0, (byte)128, (byte)0));
this.BackgroundCustomizable = new bool?(false);
this.DisplayName = "Warning";
}
}
[Export(typeof(EditorFormatDefinition))]
[Name("compiler error")]
[UserVisible(true)]
internal class CompilerErrorClassificationFormatDefinition : EditorFormatDefinition
{
public CompilerErrorClassificationFormatDefinition()
{
this.ForegroundBrush = (Brush)Brushes.Blue;
this.BackgroundCustomizable = new bool?(false);
this.DisplayName = "Compiler Error";
}
}
[Export(typeof(EditorFormatDefinition))]
[Name("other error")]
[UserVisible(true)]
internal class OtherErrorClassificationFormatDefinition : EditorFormatDefinition
{
public OtherErrorClassificationFormatDefinition()
{
this.ForegroundBrush = (Brush)new SolidColorBrush(Color.FromRgb((byte)149, (byte)23, (byte)149));
this.BackgroundCustomizable = new bool?(false);
this.DisplayName = "Other Error";
}
}
[Export(typeof(EditorFormatDefinition))]
[Name("syntax error")]
[UserVisible(true)]
internal class SyntaxErrorFormatDefinition : EditorFormatDefinition
{
public SyntaxErrorFormatDefinition()
{
this.ForegroundBrush = (Brush)Brushes.Red;
this.BackgroundCustomizable = new bool?(false);
this.DisplayName = "Syntax Error";
}
}
[Export(typeof(EditorFormatDefinition))]
[Name("hinted suggestion")]
[UserVisible(true)]
internal class HintedSuggestionClassificationFormatDefinition : EditorFormatDefinition
{
public HintedSuggestionClassificationFormatDefinition()
{
this.ForegroundBrush = (Brush)new SolidColorBrush(Color.FromRgb((byte)165, (byte)165, (byte)165));
this.BackgroundCustomizable = new bool?(false);
this.DisplayName = "Suggestion ellipses (...)";
}
}
There is one in Vs 2022 that is not included in this list. ErrorType "Edit and Continue" that by default provides a Purple brush, it is "Rude Edit" in Fonts And Colors.
If you want the squiggle colour to be edited in visual studio then set [UserVisible(true)]
on the EditorFormatDefinition and if you do so this.BackgroundCustomizable = false;
, as I have done with the ErrorEditorFormatDefinition class, given that the background is not used. Do not make user visible if you are supplying a non SolidColorBrush.
Finally, there is a different adornment for the ErrorType = PredefinedErrorTypeNames.HintedSuggestion, all others are squiggles.
Tagging
namespace also has theTextMarkerTag
, amongst others, that implementITag
. Did you read msdn.microsoft.com/en-us/library/dd885121.aspx? – BethanyErrorType
, those seem to be what VS supports: msdn.microsoft.com/en-us/library/… – Bethany