如何在visual studio扩展中的代码编辑器中获取有关鼠标位置下单词的信息

时间:2017-11-02 14:33:08

标签: visual-studio roslyn visual-studio-extensions vsix vssdk

我试图通过玩一点点来学习如何创建视觉工作室扩展 我想在代码编辑器(c#)中获取鼠标下所有关于单词的信息,但我无法弄清楚如何去做。我不想自己分析代码,因为必须有这样的机制,因为所有这些信息都在例如工具提示中(也许它足以捕获工具提示数据)。
为了更清楚:
- 如果你将鼠标悬停在变量上我想知道这个单词是一个变量,我也想要这个变量和类型的名称。任何其他类型,界面等相同 - 如果你将鼠标悬停在' var'关键字我想知道这个词是' var'关键字,我想知道它的类型。
- 如果你将鼠标悬停在类似于' List [Domain.Example.TestClass]'我希望得到的类型等于' TestClass'
与工具提示中的内容基本相同。

我试图使用' IQuickInfoSource'它允许我在光标下得到文字,但我不知道如何获得任何额外的数据 我也尝试了IMouseProcessorProvider'我得到了相同的结果,我能够得到当前的词,但任何其他信息。

你能告诉我怎么做到这一点吗?或者至少指出我正确的方向,因为很难找到关于visual studio扩展的任何适当的文档。如果您需要更多信息,请询问。

提前致谢。

2 个答案:

答案 0 :(得分:3)

经过几个小时,我能够实现我想要的目标。如果有人试图这样做,那么你可以找到以下步骤。

我正在使用'Roslyn'来获取这些信息,因此我需要下载像'Microsoft.CodeAnalysis'等的nuget软件包。

我还使用IMouseProcessorProvider来响应鼠标事件:

[Export(typeof(IMouseProcessorProvider))]
[Order]
[ContentType("CSharp")]
[Name("MouseNavigation")]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal class MouseNavigationProvider : IMouseProcessorProvider

之后使用以下代码,我能够获得类型信息

SnapshotPoint caretPosition = _textView.Caret.Position.BufferPosition;
Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
SemanticModel semanticModel = document.GetSemanticModelAsync().Result;
if (semanticModel == null)
   return null;

TypeInfo typeInfo;
SyntaxNode expressionNode = document.GetSyntaxRootAsync().Result.FindToken(caretPosition).Parent;
if (expressionNode is VariableDeclaratorSyntax)
{
    SyntaxNode childNode = expressionNode.ChildNodes()?.FirstOrDefault()
         ?.ChildNodes()?.FirstOrDefault();
    typeInfo = semanticModel.GetTypeInfo(childNode);
}
else if (expressionNode is ClassDeclarationSyntax)
{
    throw new NotImplementedException();
}
else
{
   // NOTE: This probably should be changed for specific type of syntax, but right now it is only for testing purposes
   typeInfo = semanticModel.GetTypeInfo(expressionNode);
   if (typeInfo.Type == null)
   {
        expressionNode = expressionNode.Parent;
        typeInfo = semanticModel.GetTypeInfo(expressionNode);
   }
}

答案 1 :(得分:0)

要获取有关鼠标位置下的令牌的信息,您将需要(一般而言):

  1. 实施IMouseProcessorProvider对鼠标事件做出反应
  2. 通过e.GetPosition(_view.VisualElement);获取鼠标位置
  3. 获取鼠标在文本缓冲区中的相对位置。这有点困难,因为您需要减去滚动条的宽度,等等。
  4. 获取流位置
  5. 从流位置获取SyntaxToken var document = _view.TextSnapshot.TextBuffer.GetRelatedDocuments().First(); var syntaxTree = document.GetSyntaxTreeAsync().GetAwaiter().GetResult(); var token = syntaxTree.GetRoot().FindToken(streamPosition);

完整的代码太长,无法在此处编写,无论如何都应进行解释。 VSIX: Identify mouse hover location in the editor提供了有关此主题的完整教程。