It looks like there is no official way to do that. So I implemented classifier for code comments by myself.
How to get IClassifier for the standard classification type?
-
29-06-2022 - |
Domanda
I have an extension to the MS Visual Studio editor which adds some syntax highlighting to the C++.
I want to ensure that provided SnapshotSpan has standard classification type ("comment"). There are several ways to do this:
1. I can manually parse C++ code to find comment spans. This is a last option I want to use :)
2. I can use a hack:
this.colorer = buffer.Properties.PropertyList // <-- buffer is a ITextBuffer
.Select(p => p.Value as IClassifier) // Get all classifiers someone put into the properies of the current text buffer
.Where(i => i != null)
.Where(i => i.GetType().FullName == "Microsoft.VisualC.CppColorer") // <-- Hack
.FirstOrDefault();
Now I can use this colorer (which is internal Microsoft implementation of the C++ classifier) in the following way:
this.colorer.GetClassificationSpans(span)
.Where(s => s.ClassificationType.Classification == FormatNames.Comment ||
s.ClassificationType.Classification == FormatNames.XmlDocComment)
Tada! I have information about comments in text buffer. As you understand, this a hack and I want to avoid this :)
3. I can try to get (somehow) classifier for the standard classification type (for example, for "comment").
So my question is: Is this possible to get IClassifier by classification type name?
Soluzione 2
Altri suggerimenti
You can import the IClassifierAggregatorService
:
[Import]
internal IClassifierAggregatorService classifierAggregatorService = null;
And then iterate over ClassificationSpan
to check that every classification span is of type "comment"
:
IClassifier classifier = classifierAggregatorService.GetClassifier(textBuffer);
IList<ClassificationSpan> classificationSpanList = _classifier.GetClassificationSpans(span);
foreach (ClassificationSpan classificationSpan in classificationSpanList)
{
if (classificationSpan.ClassificationType.IsOfType("comment"))
{
// ...
}
}
As an alternative to getting the IClassifierAggregatorService
, you can get an ITagAggregator<IClassificationTag>
from IBufferTagAggregatorFactoryService
. Especially useful if you want to add classification depending on a previous classification (see this answer).