2

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

我试图使用“IQuickInfoSource”,它允许我在光标下获取单词,但是我不知道如何获取任何其他数据。
我还尝试了“IMouseProcessorProvider”,最终得到了相同的结果,我能够获取当前单词,但可以获取任何其他信息。

你能告诉我如何实现这一目标吗?或者至少为我指明了正确的方向,因为很难找到任何关于 Visual Studio 扩展的适当文档。如果您需要更多信息,请询问。

提前致谢。

4

2 回答 2

3

几个小时后,我能够实现我想要的。如果有人会尝试做同样的事情,那么您可以找到以下步骤。

我正在使用“Roslyn”来获取这些信息,所以我需要下载 nuget 包,如“Microsoft.CodeAnalysis”等。

我还使用 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);
   }
}
于 2017-11-03T16:07:17.497 回答
1

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

  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提供了有关此主题的完整教程:在编辑器中识别鼠标悬停位置

于 2018-10-16T07:13:25.663 回答