IVsEditorFactory
通过为您的语言添加自定义实现并使用注册属性的组合来注册它,可以解决大多数这些项目。此接口的实际实现超出了此问题的范围,但接口本身的文档(并链接到该页面)以及Python Tools for Visual Studio项目中的示例DjangoEditorFactory
实现帮助我完成了初始实现。
为了支持示例语言,我将做出以下假设。
- 您已经实现了一个抽象类
ExampleEditorFactory
,它提供了IVsEditorFactory
. 该类应该有一个带bool
参数的受保护构造函数,以指定工厂是否应提示用户进行编码(类似于 的构造函数之一DjangoEditorFactory
)。
- 您有一个类
ExampleEditorFactoryWithoutEncoding
,它扩展ExampleEditorFactory
并构造了false
为promptForEncoding
参数指定的基类。这个类应该用[Guid]
属性来标记。
- 您有一个类
ExampleEditorFactoryWithEncoding
,它扩展ExampleEditorFactory
并构造了true
为promptForEncoding
参数指定的基类。这个类应该用[Guid]
属性来标记。
- 您已将以下条目添加到 VSPackage.resx 资源文件中。常量可以更改,但请注意,我使用了下面的常量值 101 和 102。
101 = 示例语言
102 = 带编码的示例语言
注册编辑器工厂
首先要做的是注册你的编辑器工厂。这分两部分完成。
首先,使用ProvideEditorFactoryAttribute
. 此属性将工厂显示名称的资源标识符与工厂类型本身相关联。
[ProvideEditorFactory(typeof(ExampleEditorFactoryWithoutEncoding), 101)]
[ProvideEditorFactory(typeof(ExampleEditorFactoryWithEncoding), 102)]
接下来,在 的Initialize
方法中,在调用之后ExampleLanguagePackage
添加调用。RegisterEditorFactory
base.Initialize()
protected override void Initialize()
{
base.Initialize();
RegisterEditorFactory(new ExampleEditorFactoryWithoutEncoding(this));
RegisterEditorFactory(new ExampleEditorFactoryWithEncoding(this));
}
将逻辑视图与编辑器工厂关联
我还没有找到我想要的关于ProvideEditorLogicalViewAttribute
属性用例的所有信息,但至少包括以下内容很重要。确保向您创建的两个工厂注册逻辑视图。
[ProvideEditorLogicalView(typeof(ExampleEditorFactoryWithoutEncoding), VSConstants.LOGVIEWID.TextView_string)]
[ProvideEditorLogicalView(typeof(ExampleEditorFactoryWithEncoding), VSConstants.LOGVIEWID.TextView_string)]
如果不执行此步骤,则在输出窗口中双击可以将您带到一行代码的功能将无法按预期工作。例如,假设输出窗口包含如下一行。
c:\dev\file.e1(14,3): unexpected expression
关联 TextView 逻辑视图允许 IDE 在您双击此输出行时使用您的工厂,将您带到文件 c:\dev\file.e1 的第 14 行第 3 列。否则它将使用不同的工厂打开文档的新副本,并且新窗口可能会缺少许多功能。
将标准文件扩展名.e1
和.e2
编辑器工厂关联起来
此步骤为原始问题 1 中描述的 .e1 和 .e2 文件提供“打开方式...”支持。此步骤通过ProvideEditorExtensionAttribute
属性完成。
主工厂的默认优先级似乎是 50。具有显式编码的工厂的优先级应该低于此值,而 49 似乎是一个不错的选择。请注意,无需指定NameResourceID
命名参数,因为它已由上述ProvideEditorFactoryAttribute
用法指定(生成的注册表项相同)。
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".e1", 50)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".e2", 50)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".e1", 49)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".e2", 49)]
将.*
扩展与编辑器工厂关联
此步骤为所有其他文件提供“打开方式...”支持,并添加对原始问题 2 中描述的文件扩展名选项的支持。此步骤也使用该ProvideEditorExtensionAttribute
属性,但使用低得多的优先级值以确保默认其他文件类型的编辑器不会被设置覆盖。与上一步一样,具有显式编码的工厂的优先级较低。
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".*", 2)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".*", 1)]
最后的笔记
这个答案没有涵盖几个细节。