【问题标题】:How to get information about word under mouse position in code editor in visual studio extension如何在 Visual Studio 扩展的代码编辑器中获取有关鼠标位置下单词的信息
【发布时间】:2017-11-02 14:33:07
【问题描述】:

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

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

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

提前致谢。

【问题讨论】:

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


    【解决方案1】:

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

    我正在使用“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);
       }
    }
    

    【讨论】:

    • 这似乎给了我插入符号的位置,而不是鼠标悬停位置
    【解决方案2】:

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

    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 提供有关此主题的完整教程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 2022-12-03
      • 1970-01-01
      • 2022-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多