VS2010语法着色:如何获取之前的分类类型
我正在尝试基于 Noah Richards 的 diff 着色示例来使用 VS2010 的新语法着色功能。目标是为 SpecFlow 创建语法着色 (http://www.specflow.org)。
就我而言,查找语法元素相当复杂,而且不是行级的。因此,当我实现 GetClassificationSpans 时,我不想重新解析整个文件,而是获取已更改文本开头的状态并从该点开始解析内容。
我以为我可以将之前的分类作为ClassificationTags。我使用 IBufferTagAggregatorFactoryService 类完成此操作。
它有效,但我不确定这是否是最好的方法。我应该只为整个分类器类创建标签聚合器,还是可以在每次调用 GetClassificationSpans 时创建它?我应该创建一个特殊的标签来记住解析状态吗?
也许这无论如何都不是正确的方法,我也对其他建议感兴趣。
兄弟, Gaspar
编辑:我在该主题中找到了一个很好的文章系列: http://www.hill30.com/MikeFeingoldBlog/index.php/2009/07/31/django-editor-in-vs-2010-part- 1-颜色/
I'm trying to play with the new syntax coloring capabilities of VS2010 based on Noah Richards' diff coloring sample. The goal is to create syntax coloring for SpecFlow (http://www.specflow.org).
In my case, finding the syntax elements are fairly complex and not line-level. Therefore, when I implement the GetClassificationSpans I don't want to re-parse the entire file, but rather take the state of the beginning of the changed text and parsing the content from that point on.
I thought that I can get the previous classifications as ClassificationTags. I did this using the IBufferTagAggregatorFactoryService class.
It works, but I'm not sure whether this is the best way to go. Shall I create only tag aggregator for the entire classifier class or I can create it every time when GetClassificationSpans is called? Shall I create a special tag to remember the parsing state?
Maybe this is anyway not the right way to go, I'm also interested in other suggestions.
Br,
Gaspar
Edit: I've found a good article series in the topic: http://www.hill30.com/MikeFeingoldBlog/index.php/2009/07/31/django-editor-in-vs-2010-part-1-colors/
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
本质上,您必须自己记住该状态。大多数 VS 语言服务都会在文本更改时更新的每一行的开头保留一个状态 cookie。
在任何时候,获取分类(通过分类器聚合器或标签聚合器)总是会导致调用当前分类器/标记器,因此它不会返回任何类型的缓存状态(或返回的“最后”分类) 。编辑器并没有真正缓存这些信息,只是充当分类器向正在格式化的可见行提供的信息的愚蠢传递。
另外,如果您从分类器(由 IClassifierProvider 或 ITaggerProvider 提供)执行此操作,那么您正在为自己设置一些令人讨厌的递归,特别是如果您的分类器通过调用聚合器来响应
GetClassificationSpans
(然后回调到您的分类器以获取一些较早的文本等)。如果您的分类器需要使用其他分类才能正常工作(而不是其自己的分类),那么唯一安全的编写方法是:ITagger
,并从IViewTaggerProvider
提供它。IBufferTagAggregatorFactoryService
获取ITagAggregator
,但仅一次。IDisposable
并在Dispose()
中处置标记聚合器。Essentially, you'll have to remember the state yourself. Most VS language services keep a state cookie for the beginning of each line that they update on text change.
At any point, getting classifications (through either a classifier aggregator or tag aggregator) will always result into a call into the current classifiers/taggers, so it won't be returning any type of cached state (or the "last" classifications returned). The editor doesn't really cache this information, and just acts as a dumb pass-through for the information your classifier provides to the visible lines being formatted.
Also, If you do it from a classifier (provided by either an IClassifierProvider or ITaggerProvider), you are setting yourself up for some nasty recursion, especially if your classifier responds to
GetClassificationSpans
by calling into the aggregator (which then calls back into your classifier for some earlier text, etc.). If your classifier needs to consume other classifications to work correctly (and not its own classifications), the only safe way to write that is to:ITagger<IClassificationTag>
, and provide it from anIViewTaggerProvider
.ITagAggregator<IClassificationTag>
from anIBufferTagAggregatorFactoryService
, but only once.IDisposable
on your tagger and dispose the tag aggregator inDispose()
.