VS2010语法高亮:如何获取先前的分类类型

3
我正在尝试使用Noah Richards的差异着色示例来玩转VS2010的新语法着色功能。目标是为SpecFlow(http://www.specflow.org)创建语法着色。
在我的情况下,查找语法元素相当复杂且不是基于行级别的。因此,当我实现GetClassificationSpans时,我不想重新解析整个文件,而是从更改文本的开头状态开始解析内容。
我认为可以将先前的分类作为ClassificationTags获取。我使用IBufferTagAggregatorFactoryService类实现了这一点。
它可以工作,但我不确定这是否是最佳方法。我应该为整个分类器类创建标记聚合器,还是每次调用GetClassificationSpans时都可以创建它?我应该创建一个特殊的标记以记住解析状态吗?
也许这根本不是正确的方法,我也对其他建议感兴趣。
Br, Gaspar 编辑:我在这个主题上找到了一系列好的文章:http://www.hill30.com/MikeFeingoldBlog/index.php/2009/07/31/django-editor-in-vs-2010-part-1-colors/
1个回答

4
基本上,你需要自己记住状态。大多数VS语言服务会为每行的开始保留一个状态cookie,在文本更改时更新该状态。
在任何时候,获取分类(通过分类器聚合器或标记聚合器)将始终导致调用当前分类器/标记器,因此不会返回任何类型的缓存状态(或“最后”返回的分类)。编辑器实际上并不缓存此信息,并且只是作为可见行格式提供给您的分类器提供信息的一个简单传递。
此外,如果您从分类器(由IClassifierProvider或ITaggerProvider提供)执行此操作,则可能会导致一些令人讨厌的递归,特别是如果您的分类器通过调用聚合器(然后回调到您的分类器以获取一些早期的文本等)来响应GetClassificationSpans。如果您的分类器需要消耗其他分类才能正常工作(而不是自己的分类),则编写它的唯一安全方法是:
1. 将“分类器”实现为ITagger,并从IViewTaggerProvider提供它。 2. 从IBufferTagAggregatorFactoryService获取ITagAggregator,但只获取一次。 3. 在标记器上实现IDisposable,并在Dispose()中处理标记聚合器。

谢谢你的回答!关于状态 cookies:是否有内置基础设施,还是我应该将它们存储在自己的模型中? - Gaspar Nagy
在旧的接口(IVsColorizer)中有这个功能,但在新的接口中却没有了,所以您需要自己编写模型。如果您遇到任何问题,请告诉我,因为当我将这些旧的IVsColorizer进行适配以使其与分类工作时,我也不得不编写这样的模型。 - Noah Richards

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接