在自定义编辑器中处理标准命令
-
21-12-2019 - |
题
我创建了一个 Visual Studio 扩展,通过实现提供程序语法突出显示 IClassifierProvider
. 。我想添加其他功能,例如对标准的支持 Edit.CommentSelection
和 Edit.FormatDocument
命令,但我不知道该怎么做。我能找到的所有文档都是关于添加新命令的,但我想要处理的命令已经存在。
我该如何处理这些命令?
解决方案
我考虑具体 评论选择 和 取消注释选择 您称为特殊情况的命令,因为我正在研究 评论服务 专门旨在支持这两项行动。该服务正在开发中 在 GitHub 上 准备就绪后将通过 NuGet 发布。我将从对此服务的描述开始,然后介绍一些有关实现对特定命令的支持的一般信息,包括 格式化文档 命令。
我想在本周发布该库及其依赖项,但是限制 评论者界面 装配体是 不可变的程序集 与库在首次发布之前通常进行的测试相比,需要更多的测试。幸运的是,这个特定组件中唯一的东西是两个接口 Tvl.VisualStudio.Text.Commenter.Interfaces
命名空间。
使用评论服务
该服务允许扩展开发人员轻松支持 Visual Studio 中新语言的注释和取消注释命令。
提供标准评论者
提供评论功能的最简单方法是使用标准 Commenter
的实施 ICommenter
界面。以下步骤展示了如何创建实例 Commenter
并通过导出实例将其提供给评论者服务 ICommenterProvider
.
创建一个派生自的新类
ICommenterProvider
. 。该类使用 MEF 导出ExportAttribute
对于一种或多种特定内容类型,使用ContentTypeAttribute
. 。示例中的注释器支持 C++ 风格的行注释和块注释,例如SimpleC
内容类型。[Export(typeof(ICommenterProvider))] [ContentType("SimpleC")] public sealed class SimpleCCommenterProvider : ICommenterProvider { public ICommenter GetCommenter(ITextView textView) { // TODO: provide a commenter throw new NotImplementedException(); } }
定义评论者支持的评论格式。
private static readonly LineCommentFormat LineCommentFormat = new LineCommentFormat("//"); private static readonly BlockCommentFormat BlockCommentFormat = new BlockCommentFormat("/*", "*/");
实施
GetCommenter(ITextView)
方法通过返回一个实例Commenter
. 。这ITextUndoHistoryRegistry
导入服务是为了Commenter
正确支持撤消和重做命令。下面的代码是完整的实现ICommenterProvider
需要支持简单语言的注释和取消注释命令。[Export(typeof(ICommenterProvider))] [ContentType("SimpleC")] public sealed class SimpleCCommenterProvider : ICommenterProvider { private static readonly LineCommentFormat LineCommentFormat = new LineCommentFormat("//"); private static readonly BlockCommentFormat BlockCommentFormat = new BlockCommentFormat("/*", "*/"); [Import] private ITextUndoHistoryRegistry TextUndoHistoryRegistry { get; set; } public ICommenter GetCommenter(ITextView textView) { Func<Commenter> factory = () => new Commenter(textView, TextUndoHistoryRegistry, LineCommentFormat, BlockCommentFormat); return textView.Properties.GetOrCreateSingletonProperty<Commenter>(factory); } }
Visual Studio 中的命令处理
以下是在 Visual Studio 中处理命令的一般步骤。请记住,实现细节相当复杂;我创建了一些抽象基类来简化具体的实现。在概述之后,我将指出它们及其使用的具体示例,供您参考。
- 创建一个类来实现
IOleCommandTarget
. 。这QueryStatus
方法应该检查命令目标处理的特定命令并返回适当的状态标志。这Exec
应该实现方法来执行命令。 - 通过调用将命令目标注册到特定的文本视图
IVsTextView.AddCommandFilter
. 。如果您正在使用基于 MEF 的扩展,您可以获得IVsTextView
通过导出一个实例IVsTextViewCreationListener
, ,或者通过导入IVsEditorAdaptersFactoryService
组件并使用GetViewAdapter
方法获得IVsTextView
从一个实例ITextView
.
以下是此处描述的接口的一些具体实现:
CommandFilter
:该类实现了基本要求IOleCommandTarget
TextViewCommandFilter
:此类实现了附加功能以简化命令过滤器到文本视图的附加CommenterFilter
:此类是评论服务实现用来处理命令过滤器的具体实现 评论选择 和 取消注释选择 命令