diff --git a/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs b/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs
index 2d07b02e11edd33d99e4bdeefa8b265a6eabc92b..1cd471135b90d3805569ae1edb57cea9b27f0493 100644
--- a/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs
+++ b/src/EditorFeatures/Core/EditorFeaturesResources.Designer.cs
@@ -1467,6 +1467,15 @@ internal class EditorFeaturesResources {
}
}
+ ///
+ /// Looks up a localized string similar to Suggestion ellipses (…).
+ ///
+ internal static string Suggestion_ellipses {
+ get {
+ return ResourceManager.GetString("Suggestion_ellipses", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to 'symbol' cannot be a namespace..
///
diff --git a/src/EditorFeatures/Core/EditorFeaturesResources.resx b/src/EditorFeatures/Core/EditorFeaturesResources.resx
index 006622346b14b1c8a4ccef072d619a1662d6f73d..dbe2f1d208674233147f2eac9d43f46a1cce1149 100644
--- a/src/EditorFeatures/Core/EditorFeaturesResources.resx
+++ b/src/EditorFeatures/Core/EditorFeaturesResources.resx
@@ -748,4 +748,7 @@ Do you want to proceed?
Navigating...
+
+ Suggestion ellipses (…)
+
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/Adornments/GraphicsTag.cs b/src/EditorFeatures/Core/Implementation/Adornments/GraphicsTag.cs
index 8443b37773ad6935bb930229af22d413b8855cd0..d9a0460bbef2f70f50915c51db6a3ef17ed02f4e 100644
--- a/src/EditorFeatures/Core/Implementation/Adornments/GraphicsTag.cs
+++ b/src/EditorFeatures/Core/Implementation/Adornments/GraphicsTag.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System.Diagnostics;
using System.Windows.Media;
+using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
@@ -11,31 +13,53 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Adornments
///
internal abstract class GraphicsTag : ITag
{
- protected static SolidColorBrush VerticalRuleBrush;
- protected static Color VerticalRuleColor;
+ private IEditorFormatMapService _editorFormatMapService;
+ private IEditorFormatMap _editorFormatMap;
- protected virtual void Initialize(IWpfTextView view)
+ protected virtual void Initialize(IWpfTextView view,
+ ref Brush graphicsTagBrush,
+ ref Color graphicsTagColor)
{
- if (VerticalRuleBrush != null)
+ if (graphicsTagBrush != null)
{
return;
}
+ Debug.Assert(_editorFormatMap == null);
+ _editorFormatMap = _editorFormatMapService.GetEditorFormatMap("text");
+ _editorFormatMap.FormatMappingChanged += OnFormatMappingChanged;
+
// TODO: Refresh this when the user changes fonts and colors
- // TODO: Get from resources
- var lightGray = Color.FromRgb(0xE0, 0xE0, 0xE0);
+ // If we can't get the color for some reason, fall back to a hardcoded value
+ // the editor has for outlining.
+ var lightGray = Color.FromRgb(0xA5, 0xA5, 0xA5);
+
+ var color = this.GetColor(view, _editorFormatMap) ?? lightGray;
- var outliningForegroundBrush = view.VisualElement.TryFindResource("outlining.verticalrule.foreground") as SolidColorBrush;
- var color = outliningForegroundBrush?.Color ?? lightGray;
+ graphicsTagColor = color;
+ graphicsTagBrush = new SolidColorBrush(graphicsTagColor);
+ }
- VerticalRuleColor = color;
- VerticalRuleBrush = new SolidColorBrush(VerticalRuleColor);
+ protected abstract Color? GetColor(IWpfTextView view, IEditorFormatMap editorFormatMap);
+
+ private void OnFormatMappingChanged(object sender, FormatItemsEventArgs e)
+ {
+ _editorFormatMap.FormatMappingChanged -= OnFormatMappingChanged;
+ _editorFormatMap = null;
+ this.ClearCachedFormatData();
}
+ protected abstract void ClearCachedFormatData();
+
///
/// This method allows corresponding adornment manager to ask for a graphical glyph.
///
public abstract GraphicsResult GetGraphics(IWpfTextView view, Geometry bounds);
+
+ internal void RegisterService(IEditorFormatMapService editorFormatMapService)
+ {
+ _editorFormatMapService = editorFormatMapService;
+ }
}
}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsSuggestionTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsSuggestionTaggerProvider.cs
index 7cff93fae12dc4db47139c055eee3ba7668d21b9..a372653c2fd59c012fd937fe67ac98269e428de6 100644
--- a/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsSuggestionTaggerProvider.cs
+++ b/src/EditorFeatures/Core/Implementation/Diagnostics/DiagnosticsSuggestionTaggerProvider.cs
@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Shared.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
@@ -27,11 +28,13 @@ internal partial class DiagnosticsSuggestionTaggerProvider :
[ImportingConstructor]
public DiagnosticsSuggestionTaggerProvider(
+ IEditorFormatMapService editorFormatMapService,
IDiagnosticService diagnosticService,
IForegroundNotificationService notificationService,
[ImportMany] IEnumerable> listeners)
: base(diagnosticService, notificationService, listeners)
{
+ SuggestionTag.Instance.RegisterService(editorFormatMapService);
}
protected internal override bool IncludeDiagnostic(DiagnosticData diagnostic)
diff --git a/src/EditorFeatures/Core/Implementation/Diagnostics/SuggestionTag.cs b/src/EditorFeatures/Core/Implementation/Diagnostics/SuggestionTag.cs
index ab2ff32a60cafd2f53a5784cef475cb0323b89e1..f06dd2f9ee36ce7048554b362f249dc224e0d607 100644
--- a/src/EditorFeatures/Core/Implementation/Diagnostics/SuggestionTag.cs
+++ b/src/EditorFeatures/Core/Implementation/Diagnostics/SuggestionTag.cs
@@ -1,32 +1,69 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
+using System.ComponentModel.Composition;
using System.Windows.Media;
using System.Windows.Shapes;
using Microsoft.CodeAnalysis.Editor.Implementation.Adornments;
+using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics
{
+ [Export(typeof(EditorFormatDefinition))]
+ [Name(SuggestionTagFormat.ResourceName)]
+ [UserVisible(true)]
+ internal sealed class SuggestionTagFormat : EditorFormatDefinition
+ {
+ public const string ResourceName = "SuggestionTagFormat";
+
+ public SuggestionTagFormat()
+ {
+ this.ForegroundColor = Color.FromArgb(200, 0xA5, 0xA5, 0xA5);
+ this.BackgroundCustomizable = false;
+ this.DisplayName = EditorFeaturesResources.Suggestion_ellipses;
+ }
+ }
+
///
/// Tag that specifies line separator.
///
internal class SuggestionTag : GraphicsTag
{
+ private static Brush s_graphicsTagBrush;
+ private static Color s_graphicsTagColor;
+ private static Pen s_graphicsTagPen;
+
public static readonly SuggestionTag Instance = new SuggestionTag();
- private static Pen s_pen;
+ protected override Color? GetColor(
+ IWpfTextView view, IEditorFormatMap editorFormatMap)
+ {
+ var property = editorFormatMap.GetProperties(SuggestionTagFormat.ResourceName)["ForegroundColor"];
+ return property as Color?;
+ }
+
+ protected override void ClearCachedFormatData()
+ {
+ s_graphicsTagBrush = null;
+ s_graphicsTagColor = default(Color);
+ s_graphicsTagPen = null;
+ }
- protected override void Initialize(IWpfTextView view)
+ protected override void Initialize(IWpfTextView view,
+ ref Brush graphicsTagBrush,
+ ref Color graphicsTagColor)
{
- base.Initialize(view);
+ base.Initialize(view, ref graphicsTagBrush, ref graphicsTagColor);
- if (s_pen != null)
+ if (s_graphicsTagPen != null)
{
return;
}
- var color = Color.FromArgb(200, VerticalRuleColor.R, VerticalRuleColor.G, VerticalRuleColor.B);
- s_pen = new Pen
+ var color = graphicsTagColor;
+ s_graphicsTagPen = new Pen
{
Brush = new SolidColorBrush(color),
DashStyle = DashStyles.Dot,
@@ -37,7 +74,7 @@ protected override void Initialize(IWpfTextView view)
public override GraphicsResult GetGraphics(IWpfTextView view, Geometry geometry)
{
- Initialize(view);
+ Initialize(view, ref s_graphicsTagBrush, ref s_graphicsTagColor);
// We clip off a bit off the start of the line to prevent a half-square being
// drawn.
@@ -47,17 +84,17 @@ public override GraphicsResult GetGraphics(IWpfTextView view, Geometry geometry)
var line = new Line
{
X1 = geometry.Bounds.Left,
- Y1 = geometry.Bounds.Bottom - s_pen.Thickness,
+ Y1 = geometry.Bounds.Bottom - s_graphicsTagPen.Thickness,
X2 = geometry.Bounds.Right,
- Y2 = geometry.Bounds.Bottom - s_pen.Thickness,
+ Y2 = geometry.Bounds.Bottom - s_graphicsTagPen.Thickness,
Clip = new RectangleGeometry { Rect = clipRectangle }
};
// RenderOptions.SetEdgeMode(line, EdgeMode.Aliased);
- ApplyPen(line, s_pen);
+ ApplyPen(line, s_graphicsTagPen);
// Shift the line over to offset the clipping we did.
- line.RenderTransform = new TranslateTransform(-s_pen.Thickness, 0);
+ line.RenderTransform = new TranslateTransform(-s_graphicsTagPen.Thickness, 0);
return new GraphicsResult(line, null);
}
diff --git a/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTag.cs b/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTag.cs
index f60b309e17e28a8f6e56a7c964bc770048027d6d..41909f4f85493c4a596992b90c4ecfd38fa418fd 100644
--- a/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTag.cs
+++ b/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTag.cs
@@ -5,6 +5,7 @@
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.CodeAnalysis.Editor.Implementation.Adornments;
+using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
namespace Microsoft.CodeAnalysis.Editor.Implementation.LineSeparators
@@ -14,17 +15,33 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.LineSeparators
///
internal class LineSeparatorTag : GraphicsTag
{
+ private static Brush s_graphicsTagBrush;
+ private static Color s_graphicsTagColor;
+
public static readonly LineSeparatorTag Instance = new LineSeparatorTag();
+ protected override Color? GetColor(
+ IWpfTextView view, IEditorFormatMap editorFormatMap)
+ {
+ var brush = view.VisualElement.TryFindResource("outlining.verticalrule.foreground") as SolidColorBrush;
+ return brush?.Color;
+ }
+
+ protected override void ClearCachedFormatData()
+ {
+ s_graphicsTagBrush = null;
+ s_graphicsTagColor = default(Color);
+ }
+
///
/// Creates a very long line at the bottom of bounds.
///
public override GraphicsResult GetGraphics(IWpfTextView view, Geometry bounds)
{
- Initialize(view);
+ Initialize(view, ref s_graphicsTagBrush, ref s_graphicsTagColor);
var border = new Border();
- border.BorderBrush = VerticalRuleBrush;
+ border.BorderBrush = s_graphicsTagBrush;
border.BorderThickness = new Thickness(0, 0, 0, bottom: 1);
border.Height = 1;
border.Width = view.ViewportWidth;
@@ -45,4 +62,4 @@ public override GraphicsResult GetGraphics(IWpfTextView view, Geometry bounds)
() => view.ViewportWidthChanged -= viewportWidthChangedHandler);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTaggerProvider.cs
index b99fd02edba1ccd189d786ac643a275d876f3619..9cb319905f88888443284ba80cf36e2195c4edb2 100644
--- a/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTaggerProvider.cs
+++ b/src/EditorFeatures/Core/Implementation/LineSeparators/LineSeparatorTaggerProvider.cs
@@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
@@ -34,13 +35,16 @@ internal partial class LineSeparatorTaggerProvider : AsynchronousTaggerProvider<
[ImportingConstructor]
public LineSeparatorTaggerProvider(
+ IEditorFormatMapService editorFormatMapService,
IForegroundNotificationService notificationService,
[ImportMany] IEnumerable> asyncListeners)
: base(new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.LineSeparators), notificationService)
{
+ LineSeparatorTag.Instance.RegisterService(editorFormatMapService);
}
- protected override ITaggerEventSource CreateEventSource(ITextView textViewOpt, ITextBuffer subjectBuffer)
+ protected override ITaggerEventSource CreateEventSource(
+ ITextView textView, ITextBuffer subjectBuffer)
{
return TaggerEventSources.OnTextChanged(subjectBuffer, TaggerDelay.NearImmediate);
}
diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.cs
index 73b51229dac6e1884c9fd6dff13263ce33e7a2ed..2e77828c4905d029bf3b9e52daf9dc3b82ca7baf 100644
--- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.cs
+++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.cs
@@ -109,9 +109,12 @@ private TagSource CreateTagSource(ITextView textViewOpt, ITextBuffer subjectBuff
}
var tagSource = GetOrCreateTagSource(textViewOpt, subjectBuffer);
- return tagSource == null
- ? null
- : new Tagger(_asyncListener, _notificationService, tagSource, subjectBuffer) as IAccurateTagger;
+ if (tagSource == null)
+ {
+ return null;
+ }
+
+ return new Tagger(_asyncListener, _notificationService, tagSource, subjectBuffer) as IAccurateTagger;
}
private TagSource GetOrCreateTagSource(ITextView textViewOpt, ITextBuffer subjectBuffer)