在自定义编辑器中处理标准命令

时间:2014-07-29 10:49:12

标签: visual-studio-2012 editor vsix

我创建了一个Visual Studio扩展,通过实现IClassifierProvider提供语法高亮显示。我想添加其他功能,例如支持标准Edit.CommentSelectionEdit.FormatDocument命令,但我不知道如何做到这一点。我能找到的所有文档都是关于添加新命令,但我想要处理的命令已经存在。

我该如何处理这些命令?

1 个答案:

答案 0 :(得分:1)

我考虑了特定的评论选择取消注释选择命令,因为我正在处理Commenter Service特定用途支持这两个行动。该服务正在开发on GitHub,并将在准备好后通过NuGet发布。我将首先介绍此服务,并按照一些有关实现特定命令支持的一般信息,包括格式文档命令。

我想在本周发布库及其依赖项,但是Commenter Interfaces程序集为immutable assembly的限制要求比初始发布之前通常给予库的测试更多。幸运的是,这个特定程序集中唯一的两个接口是Tvl.VisualStudio.Text.Commenter.Interfaces命名空间。

使用评论者服务

  

来源:Commenter Service (Tunnel Vision Labs' Base Extensions Library for Visual Studio)

此服务允许扩展开发人员轻松支持Visual Studio中新语言的Comment和Uncomment命令。

提供标准评论者

提供评论功能的最简单方法是使用Commenter接口的标准ICommenter实现。以下步骤说明如何创建Commenter的实例,并通过导出ICommenterProvider的实例将其提供给评论者服务。

  1. 创建一个派生自ICommenterProvider的新类。使用ExportAttribute,使用MEF ContentTypeAttribute为一个或多个特定内容类型导出此类。该示例中的评论者支持SimpleC内容类型的C ++样式行和块注释。

    [Export(typeof(ICommenterProvider))]
    [ContentType("SimpleC")]
    public sealed class SimpleCCommenterProvider : ICommenterProvider
    {
      public ICommenter GetCommenter(ITextView textView)
      {
        // TODO: provide a commenter 
        throw new NotImplementedException();
      }
    }
    
  2. 定义评论者将支持的评论格式。

    private static readonly LineCommentFormat LineCommentFormat =
      new LineCommentFormat("//");
    private static readonly BlockCommentFormat BlockCommentFormat =
      new BlockCommentFormat("/*", "*/");
    
  3. 通过返回GetCommenter(ITextView)的实例来实现Commenter方法。导入ITextUndoHistoryRegistry服务,以便Commenter正确支持撤消和重做命令。以下代码是支持简单语言的Comment和Uncomment命令所需的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);
      }
    }
    
  4. Visual Studio中的命令处理

    以下是在Visual Studio中处理命令的一般步骤。请记住,实现细节非常复杂;我已经创建了一些抽象基类来简化特定的实现。在概述之后,我将指出它们以及它们用于引用的具体示例。

    1. 创建一个实现IOleCommandTarget的类。 QueryStatus方法应检查命令目标处理的特定命令,并返回相应的状态标志。应该实现Exec方法来执行命令。
    2. 通过调用IVsTextView.AddCommandFilter向特定文本视图注册命令目标。如果您使用的是基于MEF的扩展程序,则可以通过导出IVsTextViewCreationListener的实例,或导入IVsEditorAdaptersFactoryService组件并使用GetViewAdapter来获取IVsTextViewIVsTextView
    3. 的实例获取ITextView的方法

      以下是此处描述的接口的一些具体实现:

      1. CommandFilter:此类实现IOleCommandTarget
      2. 的基本要求
      3. TextViewCommandFilter:此类实现了其他功能,以简化命令过滤器与文本视图的连接。
      4. CommenterFilter:此类是Commenter Service实现用于处理注释选择取消注释选择命令的命令过滤器的具体实现