Skip to content

Commit

Permalink
- Fix #333 (C# syntax highlight stopped working after Copy/Cut operat…
Browse files Browse the repository at this point in the history
…ion with "Copy rich text on copy/cut" option turned on)
  • Loading branch information
wmjordan committed Aug 30, 2024
1 parent a91e3fd commit a170f5e
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 11 deletions.
15 changes: 8 additions & 7 deletions Codist/Semantics/CSharpParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,17 @@ public TextBufferParser(CSharpParser container, ITextBuffer buffer) {

public event EventHandler<EventArgs<SemanticState>> StateUpdated;

internal bool IsDisposed => _Parser == null;
public bool IsDisposed => _Parser == null;
public ITextBuffer TextBuffer => _Buffer;

public void Ref() {
_Ref++;
Debug.WriteLine($"Ref+ {_Ref} {_Name}");
$"Ref+ {_Ref} {_Name}".Log();
}

internal void Release() {
if (Interlocked.Exchange(ref _Parser, null) != null) {
Debug.WriteLine($"{_Name} tagger released");
$"{_Name} tagger released".Log();
ReleaseResources();
_Ref = 0;
}
Expand Down Expand Up @@ -274,7 +274,7 @@ void UnsubscribeBufferEvents(ITextBuffer buffer) {
}

void WorkspaceChanged(object sender, WorkspaceChangeEventArgs args) {
Debug.WriteLine($"Workspace {args.Kind}: {args.DocumentId}");
$"Workspace {args.Kind}: {args.DocumentId}".Log();
var parser = _Parser;
if (parser == null) {
return;
Expand Down Expand Up @@ -308,17 +308,18 @@ void WorkspaceChanged(object sender, WorkspaceChangeEventArgs args) {
void TextBuffer_ContentTypeChanged(object sender, ContentTypeChangedEventArgs e) {
if (_IsInteractiveWindow == false
&& e.AfterContentType.IsOfType(Constants.CodeTypes.CSharp) == false) {
$"ContentType changed to {e.AfterContentType.DisplayName}".Log();
Dispose();
}
}

public void Dispose() {
if (--_Ref > 0) {
Debug.WriteLine($"Ref- {_Ref} {_Name}");
$"Ref- {_Ref} {_Name}".Log();
return;
}
if (Interlocked.Exchange(ref _Parser, null) != null) {
Debug.WriteLine($"{_Name} tagger disposed");
$"{_Name} tagger disposed".Log();
ReleaseResources();
}
}
Expand Down Expand Up @@ -402,7 +403,7 @@ async Task ParseAsync(Workspace workspace, Document document, ITextSnapshot snap
throw;
}
if (Interlocked.CompareExchange(ref _State, (int)ParserState.Completed, (int)ParserState.Working) == (int)ParserState.Working) {
Debug.WriteLine($"{snapshot.TextBuffer.GetDocument().GetDocId()} end parsing {snapshot.Version} on thread {Thread.CurrentThread.ManagedThreadId}");
$"{snapshot.TextBuffer.GetDocument().GetDocId()} end parsing {snapshot.Version} on thread {Thread.CurrentThread.ManagedThreadId}".Log();
_Callback(new SemanticState(workspace, model, snapshot, document));
Interlocked.CompareExchange(ref _State, (int)ParserState.Idle, (int)ParserState.Completed);
}
Expand Down
1 change: 1 addition & 0 deletions Codist/Semantics/ITextBufferParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Codist
interface ITextBufferParser : IDisposable
{
ITextBuffer TextBuffer { get; }
bool IsDisposed { get; }

/// <summary>
/// Gets <see cref="SemanticState"/> from given <see cref="ITextSnapshot"/>. If the <paramref name="snapshot"/> is not the same as the <see cref="SemanticState.Snapshot"/> in the <paramref name="state"/>, a new parsing will be scheduled. After the parsing, the semantic state can be retrieved via the <see cref="StateUpdated"/> event.
Expand Down
16 changes: 12 additions & 4 deletions Codist/Taggers/CSharpTagger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,18 @@ sealed class CSharpTagger : ITagger<IClassificationTag>, IDisposable

ConcurrentQueue<SnapshotSpan> _PendingSpans = new ConcurrentQueue<SnapshotSpan>();
CancellationTokenSource _RenderBreaker;

int _Ref;
ITextBufferParser _Parser;

public CSharpTagger(CSharpParser parser, ITextBuffer buffer) {
_Parser = parser.GetParser(buffer);
_Parser.StateUpdated += HandleParseResult;
Ref();
}

public bool Disabled { get; set; }
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;

void HandleParseResult(object sender, EventArgs<SemanticState> result) {
var pendingSpans = _PendingSpans;
if (pendingSpans != null) {
Expand All @@ -48,9 +52,6 @@ void HandleParseResult(object sender, EventArgs<SemanticState> result) {
}
}

public bool Disabled { get; set; }
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;

public IEnumerable<ITagSpan<IClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
var p = _Parser;
if (p == null || Disabled) {
Expand Down Expand Up @@ -80,7 +81,14 @@ static IEnumerable<SnapshotSpan> MapToOldSpans(NormalizedSnapshotSpanCollection
}
}

public void Ref() {
++_Ref;
}

public void Dispose() {
if (_Ref-- > 0) {
return;
}
_PendingSpans = null;
SyncHelper.CancelAndDispose(ref _RenderBreaker, false);
ITextBufferParser t = _Parser;
Expand Down
1 change: 1 addition & 0 deletions Codist/Taggers/TaggerFactories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ ITagger<IClassificationTag> GetTagger(ITextView textView, ITextBuffer buffer) {
return null;
}
if (_LastView == textView && _LastTextBuffer == buffer) {
_LastTagger.Ref();
return _LastTagger;
}

Expand Down

0 comments on commit a170f5e

Please sign in to comment.