我找到了两种在互联网上提供语言服务的方法。
The first way涉及使用IOleComponentManager
并注册计时器以在空闲时间调用我的服务。
The second way涉及将我的服务设为IServiceContainer
并添加ServiceCreatorCallback
以“按需提供服务”。
据说第二种方式现在是做事的“首选方式”。不幸的是,当我使用这种方法时,我的OnSynchronizeDropdowns
实现永远不会调用TypeAndMembersDropdownBars
。
此外,当我的LanguageService
在文件中发现错误时,它会使用ParseRequest.Sink.AddError()
将错误添加到错误列表中。在提供“按需”时,这些错误不会显示在GUI中,即使我在调试代码时看到它们被添加。
我知道我的语言服务正在注册,因为语法高亮,“转到定义”和“查找所有引用”仍然有效。
以下是我用来“按需提供服务”的代码:
IServiceContainer serviceContainer = this as IServiceContainer;
ServiceCreatorCallback callback = new ServiceCreatorCallback(CreateLanguageService);
serviceContainer.AddService(typeof(MyLanguageService), callback, true);
任何人都可以告诉我为什么LanguageService
的某些功能在按需提供时不起作用?我是否遗漏了某些内容,或者这种方式不适用于功能齐全的语言服务?
答案 0 :(得分:1)
看起来至少缺少的功能需要使用IOleComponentManager
方法注册计时器以在空闲时段期间调用语言服务。
使用dotPeek,我发现OnSynchronizeDropdowns()
从OnCaretMoved()
调用,以便在编辑器中单击时同步所选项目。 OnCaretMoved()
本身似乎只能从LanguageService.OnIdle()
方法调用,我相信这需要使用空闲计时器。
在挖掘了更多内容后,我还发现错误列表要求ParseRequest.Reason
设置为ParseReason.Check
,否则会忽略该调用。再挖掘一下代码,我发现使用解析原因的唯一地方是Source.OnIdle()
。
更新:我相信我已经确认这两项功能需要注册空闲计时器。来自LanguageService.OnIdle上的MSDN:
注意强> 除非您设置自己的计时器并调用,否则不会调用此方法 这个方法来自计时器处理程序。
如果插入符号自上次移动后,基本方法将调用OnCaretMoved 时间 OnIdle 被调用。然后,基本方法调用OnIdle方法 在当前视图的Source对象上。如果是当前Source 无法获取对象,基本方法什么都不做, 包括不调用OnCaretMoved。