Skip to content

Commit

Permalink
Make sure only a single SameWordHighlighter is attached to a textbuffer.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
RobertvanderHulst committed Jun 26, 2023
1 parent 04a50d3 commit d9f2a84
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 23 deletions.
18 changes: 17 additions & 1 deletion demo/VSSDK.TestExtension/MEF/HighlightWord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,25 @@
using Community.VisualStudio.Toolkit;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text.Editor;

using Microsoft.VisualStudio.Text.Classification;
using System.Windows.Media;
namespace TestExtension.MEF
{

[Export(typeof(EditorFormatDefinition))]
[Name("MarkerFormatDefinition/HighlightWordFormatDefinition")]
[UserVisible(true)]
internal class HighlightWordFormatDefinition : MarkerFormatDefinition
{
public HighlightWordFormatDefinition()
{
this.BackgroundColor = Colors.LightBlue;
this.ForegroundColor = Colors.DarkBlue;
this.DisplayName = "Highlight Word";
this.ZOrder = 5;
}
}

/// <summary>
/// This class demonstrates a HighlightWord tagger for text files
/// and it only highlights whole words starting with a Letter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where
{
ITextStructureNavigator? navigator = _textStructureNavigatorSelector?.GetTextStructureNavigator(textView.TextBuffer);

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

return (ITagger<T>)tagger;
}
Expand All @@ -62,10 +62,9 @@ internal class HighlightWordTag : TextMarkerTag
public HighlightWordTag(string tagName) : base(tagName) { }
}

internal class SameWordHighlighterTagger : ITagger<HighlightWordTag>, IDisposable
internal class SameWordHighlighterTagger : ITagger<HighlightWordTag>
{
internal int Counter;
private readonly ITextView _view;
private readonly ITextBuffer _buffer;
private readonly ITextSearchService? _textSearchService;
private readonly ITextStructureNavigator? _textStructureNavigator;
Expand All @@ -74,30 +73,52 @@ internal class SameWordHighlighterTagger : ITagger<HighlightWordTag>, IDisposabl
private SnapshotSpan? _currentWord;
private SnapshotPoint _requestedPoint;
private bool _isDisposed;
private string _fileName="";
private readonly object _syncLock = new();

public SameWordHighlighterTagger(ITextView view, ITextBuffer sourceBuffer, ITextSearchService? textSearchService,
ITextStructureNavigator? textStructureNavigator, SameWordHighlighterBase tagger)
{
_view = view;
_fileName = sourceBuffer.GetFileName();
System.Diagnostics.Debug.WriteLine("Create new tagger for "+_fileName);
_buffer = sourceBuffer;
_textSearchService = textSearchService;
_textStructureNavigator = textStructureNavigator;
_tagger = tagger;
_wordSpans = new NormalizedSnapshotSpanCollection();
_currentWord = null;
_view.Caret.PositionChanged += CaretPositionChanged;
_view.LayoutChanged += ViewLayoutChanged;
Counter = 0;
}

internal void RegisterEvents(ITextView textView)
{

textView.Caret.PositionChanged += CaretPositionChanged;
textView.LayoutChanged += ViewLayoutChanged;
textView.Closed += TextView_Closed;
Counter += 1;
System.Diagnostics.Debug.WriteLine($"RegisterEvents {_fileName}: #{Counter} ");
}
internal void UnRegisterEvents(ITextView textView)
{
textView.Caret.PositionChanged -= CaretPositionChanged;
textView.LayoutChanged -= ViewLayoutChanged;
textView.Closed -= TextView_Closed;
Counter -= 1;
System.Diagnostics.Debug.WriteLine($"UnRegisterEvents {_fileName}: #{Counter} ");
}
private void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
if (e.NewSnapshot != e.OldSnapshot)
{
UpdateAtCaretPosition(_view.Caret.Position);
var view = (ITextView)sender;
UpdateAtCaretPosition(view.Caret.Position);
}
}
private void TextView_Closed(object sender, EventArgs e)
{
UnRegisterEvents((ITextView)sender);
}

private void CaretPositionChanged(object sender, CaretPositionChangedEventArgs e)
{
Expand Down Expand Up @@ -228,20 +249,6 @@ public IEnumerable<ITagSpan<HighlightWordTag>> GetTags(NormalizedSnapshotSpanCol
}
}

public void Dispose()
{
if (!_isDisposed)
{
this.Counter -= 1;
if (this.Counter == 0)
{
_view.Caret.PositionChanged -= CaretPositionChanged;
_view.LayoutChanged -= ViewLayoutChanged;
_isDisposed = true;
}
}
}

public event EventHandler<SnapshotSpanEventArgs>? TagsChanged;
}
}

0 comments on commit d9f2a84

Please sign in to comment.