使用 Visual Studio SDK 确定插入符是否在注释块中
Determine if the caret is in a comment block with Visual Studio SDK
场景
我只想在插入符号位于 Xml 注释块中时启用自定义菜单中的命令
''' ... If caret is here, in a Vb.Net Xml comment block.
或
/// ... If caret is here, in a C# Xml comment block.
然后,一个预期结果的伪代码:
C#:
private void CmdExample_BeforeQueryStatus(object sender, EventArgs e) {
// Enable this command only if the caret is in a Xml comment block.
((OleMenuCommand)sender).Enabled = IsCaretInXmlComment?();
}
Vb:
Private Sub CmdExample_BeforeQueryStatus(ByVal sender As Object, ByVal e As EventArgs) _
Handles cmdExample.BeforeQueryStatus
' Enable this command only if the caret is in a Xml comment block.
DirectCast(sender, OleMenuCommand).Enabled = IsCaretInXmlComment?()
End Sub
问题
只是,我怎么能做到呢?。在 Vb.Net 或 C# 中。
研究
我不确定该怎么做,所以我对 vsCMElement
枚举的值进行了反复试验,因为我看到了类似的东西 here,但是 CodeElement2.Kind
属性 总是抛出一个 NullReferenceException
.
C#:
TextPoint tp =
((TextSelection)MyDte.ActiveDocument.Selection).ActivePoint;
CodeElement2 ce =
MyDte.ActiveDocument.ProjectItem.FileCodeModel.
CodeElementFromPoint(tp, vsCMElement.vsCMElementOther);
Vb:
Dim tp As TextPoint =
CType(MyDte.ActiveDocument.Selection, TextSelection).ActivePoint
Dim ce As CodeElement2 =
MyDte.ActiveDocument.ProjectItem.FileCodeModel.
CodeElementFromPoint(tp, vsCMElement.vsCMElementOther)
我也发现了这个question,但是没有说明性的代码示例我对此很迷茫。
如果您的目标是 Visual Studio 2015 年或更高版本,最好的方法是使用 Roslyn。有了它,您可以获得语法树,然后确定您是否在评论中。如果你看看我们对 IsEntirelyWithinSingleLineDocComment 的实现,你就会明白我们今天是如何做到的。如果您是 Roslyn 的新手,已经有一些现有的问题可以帮助您获得语法树。
如果您需要定位低于该版本的版本,那么自从 Roslyn 于 2012 年首次发布以来,您就有麻烦了。一种常见的方法是询问分类信息,以确定某些内容是否是注释.分类是驱动您在编辑器中看到的文本着色的因素。如果您的文件得到 ITextBuffer
,那么您可以 MEF 导入 IClassifierAggregatorService
并请求分类,然后过滤到文档注释类型。 Noah Richard's original spell check sample 是如何做到这一点的一个很好的例子。
场景
我只想在插入符号位于 Xml 注释块中时启用自定义菜单中的命令
''' ... If caret is here, in a Vb.Net Xml comment block.
或
/// ... If caret is here, in a C# Xml comment block.
然后,一个预期结果的伪代码:
C#:
private void CmdExample_BeforeQueryStatus(object sender, EventArgs e) {
// Enable this command only if the caret is in a Xml comment block.
((OleMenuCommand)sender).Enabled = IsCaretInXmlComment?();
}
Vb:
Private Sub CmdExample_BeforeQueryStatus(ByVal sender As Object, ByVal e As EventArgs) _
Handles cmdExample.BeforeQueryStatus
' Enable this command only if the caret is in a Xml comment block.
DirectCast(sender, OleMenuCommand).Enabled = IsCaretInXmlComment?()
End Sub
问题
只是,我怎么能做到呢?。在 Vb.Net 或 C# 中。
研究
我不确定该怎么做,所以我对 vsCMElement
枚举的值进行了反复试验,因为我看到了类似的东西 here,但是 CodeElement2.Kind
属性 总是抛出一个 NullReferenceException
.
C#:
TextPoint tp =
((TextSelection)MyDte.ActiveDocument.Selection).ActivePoint;
CodeElement2 ce =
MyDte.ActiveDocument.ProjectItem.FileCodeModel.
CodeElementFromPoint(tp, vsCMElement.vsCMElementOther);
Vb:
Dim tp As TextPoint =
CType(MyDte.ActiveDocument.Selection, TextSelection).ActivePoint
Dim ce As CodeElement2 =
MyDte.ActiveDocument.ProjectItem.FileCodeModel.
CodeElementFromPoint(tp, vsCMElement.vsCMElementOther)
我也发现了这个question,但是没有说明性的代码示例我对此很迷茫。
如果您的目标是 Visual Studio 2015 年或更高版本,最好的方法是使用 Roslyn。有了它,您可以获得语法树,然后确定您是否在评论中。如果你看看我们对 IsEntirelyWithinSingleLineDocComment 的实现,你就会明白我们今天是如何做到的。如果您是 Roslyn 的新手,已经有一些现有的问题可以帮助您获得语法树。
如果您需要定位低于该版本的版本,那么自从 Roslyn 于 2012 年首次发布以来,您就有麻烦了。一种常见的方法是询问分类信息,以确定某些内容是否是注释.分类是驱动您在编辑器中看到的文本着色的因素。如果您的文件得到 ITextBuffer
,那么您可以 MEF 导入 IClassifierAggregatorService
并请求分类,然后过滤到文档注释类型。 Noah Richard's original spell check sample 是如何做到这一点的一个很好的例子。