Question

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?

Was it helpful?

Solution 2

It looks like there is no official way to do that. So I implemented classifier for code comments by myself.

OTHER TIPS

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top