Skip to content

Commit d9f2a84

Browse files
Make sure only a single SameWordHighlighter is attached to a textbuffer.
Each TextView will register its events itself with the tagger from the textbuffer and when the textview is closed then the events are unregistered again. The previous implementation was allocating way too many samewordhighlighters. Also changed the color for the same word highlighters in the example code.
1 parent 04a50d3 commit d9f2a84

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

demo/VSSDK.TestExtension/MEF/HighlightWord.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,25 @@
44
using Community.VisualStudio.Toolkit;
55
using System.ComponentModel.Composition;
66
using Microsoft.VisualStudio.Text.Editor;
7-
7+
using Microsoft.VisualStudio.Text.Classification;
8+
using System.Windows.Media;
89
namespace TestExtension.MEF
910
{
11+
12+
[Export(typeof(EditorFormatDefinition))]
13+
[Name("MarkerFormatDefinition/HighlightWordFormatDefinition")]
14+
[UserVisible(true)]
15+
internal class HighlightWordFormatDefinition : MarkerFormatDefinition
16+
{
17+
public HighlightWordFormatDefinition()
18+
{
19+
this.BackgroundColor = Colors.LightBlue;
20+
this.ForegroundColor = Colors.DarkBlue;
21+
this.DisplayName = "Highlight Word";
22+
this.ZOrder = 5;
23+
}
24+
}
25+
1026
/// <summary>
1127
/// This class demonstrates a HighlightWord tagger for text files
1228
/// and it only highlights whole words starting with a Letter

src/toolkit/Community.VisualStudio.Toolkit.Shared/MEF/SameWordHighlighterBase.cs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where
4949
{
5050
ITextStructureNavigator? navigator = _textStructureNavigatorSelector?.GetTextStructureNavigator(textView.TextBuffer);
5151

52-
var tagger = textView.Properties.GetOrCreateSingletonProperty(() =>
52+
var tagger = buffer.Properties.GetOrCreateSingletonProperty(() =>
5353
new SameWordHighlighterTagger(textView, buffer, _textSearchService, navigator, this));
54-
tagger.Counter += 1;
54+
tagger.RegisterEvents(textView);
5555

5656
return (ITagger<T>)tagger;
5757
}
@@ -62,10 +62,9 @@ internal class HighlightWordTag : TextMarkerTag
6262
public HighlightWordTag(string tagName) : base(tagName) { }
6363
}
6464

65-
internal class SameWordHighlighterTagger : ITagger<HighlightWordTag>, IDisposable
65+
internal class SameWordHighlighterTagger : ITagger<HighlightWordTag>
6666
{
6767
internal int Counter;
68-
private readonly ITextView _view;
6968
private readonly ITextBuffer _buffer;
7069
private readonly ITextSearchService? _textSearchService;
7170
private readonly ITextStructureNavigator? _textStructureNavigator;
@@ -74,30 +73,52 @@ internal class SameWordHighlighterTagger : ITagger<HighlightWordTag>, IDisposabl
7473
private SnapshotSpan? _currentWord;
7574
private SnapshotPoint _requestedPoint;
7675
private bool _isDisposed;
76+
private string _fileName="";
7777
private readonly object _syncLock = new();
7878

7979
public SameWordHighlighterTagger(ITextView view, ITextBuffer sourceBuffer, ITextSearchService? textSearchService,
8080
ITextStructureNavigator? textStructureNavigator, SameWordHighlighterBase tagger)
8181
{
82-
_view = view;
82+
_fileName = sourceBuffer.GetFileName();
83+
System.Diagnostics.Debug.WriteLine("Create new tagger for "+_fileName);
8384
_buffer = sourceBuffer;
8485
_textSearchService = textSearchService;
8586
_textStructureNavigator = textStructureNavigator;
8687
_tagger = tagger;
8788
_wordSpans = new NormalizedSnapshotSpanCollection();
8889
_currentWord = null;
89-
_view.Caret.PositionChanged += CaretPositionChanged;
90-
_view.LayoutChanged += ViewLayoutChanged;
9190
Counter = 0;
9291
}
9392

93+
internal void RegisterEvents(ITextView textView)
94+
{
95+
96+
textView.Caret.PositionChanged += CaretPositionChanged;
97+
textView.LayoutChanged += ViewLayoutChanged;
98+
textView.Closed += TextView_Closed;
99+
Counter += 1;
100+
System.Diagnostics.Debug.WriteLine($"RegisterEvents {_fileName}: #{Counter} ");
101+
}
102+
internal void UnRegisterEvents(ITextView textView)
103+
{
104+
textView.Caret.PositionChanged -= CaretPositionChanged;
105+
textView.LayoutChanged -= ViewLayoutChanged;
106+
textView.Closed -= TextView_Closed;
107+
Counter -= 1;
108+
System.Diagnostics.Debug.WriteLine($"UnRegisterEvents {_fileName}: #{Counter} ");
109+
}
94110
private void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
95111
{
96112
if (e.NewSnapshot != e.OldSnapshot)
97113
{
98-
UpdateAtCaretPosition(_view.Caret.Position);
114+
var view = (ITextView)sender;
115+
UpdateAtCaretPosition(view.Caret.Position);
99116
}
100117
}
118+
private void TextView_Closed(object sender, EventArgs e)
119+
{
120+
UnRegisterEvents((ITextView)sender);
121+
}
101122

102123
private void CaretPositionChanged(object sender, CaretPositionChangedEventArgs e)
103124
{
@@ -228,20 +249,6 @@ public IEnumerable<ITagSpan<HighlightWordTag>> GetTags(NormalizedSnapshotSpanCol
228249
}
229250
}
230251

231-
public void Dispose()
232-
{
233-
if (!_isDisposed)
234-
{
235-
this.Counter -= 1;
236-
if (this.Counter == 0)
237-
{
238-
_view.Caret.PositionChanged -= CaretPositionChanged;
239-
_view.LayoutChanged -= ViewLayoutChanged;
240-
_isDisposed = true;
241-
}
242-
}
243-
}
244-
245252
public event EventHandler<SnapshotSpanEventArgs>? TagsChanged;
246253
}
247254
}

0 commit comments

Comments
 (0)