如何在 visual studio 扩展中的代码编辑器中获取有关鼠标位置下的单词的信息
How to get information about word under mouse position in code editor in visual studio extension
我正在尝试通过尝试来学习如何创建 visual studio 扩展程序。
我想在代码编辑器 (c#) 中获取有关鼠标下单词的所有信息,但我不知道该怎么做。我不想自己分析代码,因为必须有这样的机制,因为所有这些信息都在例如工具提示中(也许足以捕获工具提示数据)。
为了使这一点更清楚:
-如果你将鼠标悬停在变量上我想知道这个词是一个变量我也想知道这个变量的名称和类型。对于任何其他类型、接口等也是如此。
- 如果您将鼠标悬停在 'var' 关键字上,我想知道这个词是 'var' 关键字,我想知道它的类型。
-如果您将鼠标悬停在 class 内部的 'List[Domain.Example.TestClass]' 之类的泛型上,我想获得等于 'TestClass'
的类型
工具提示中的内容基本相同。
我正在尝试使用 'IQuickInfoSource',它允许我在光标下获取单词,但是我不知道如何获取任何其他数据。
我也尝试了 'IMouseProcessorProvider',但我得到了相同的结果,我能够获得当前单词但任何其他信息。
你能告诉我如何实现吗?或者至少给我指出正确的方向,因为很难找到任何关于 visual studio 扩展的适当文档。如果您需要更多信息,请询问。
提前致谢。
几个小时后,我实现了我想要的。如果有人会尝试做同样的事情,那么您可以在下面找到步骤。
我正在使用 '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);
}
}
要获取有关鼠标位置下令牌的信息,您需要(一般而言):
- 实施
IMouseProcessorProvider
以响应鼠标事件
- 使用
e.GetPosition(_view.VisualElement);
获取鼠标位置
- 获取鼠标在文本缓冲区中的相对位置。这有点困难,因为您需要减去滚动条的宽度等等。
- 获取流位置
- 从流位置获取 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。
我正在尝试通过尝试来学习如何创建 visual studio 扩展程序。
我想在代码编辑器 (c#) 中获取有关鼠标下单词的所有信息,但我不知道该怎么做。我不想自己分析代码,因为必须有这样的机制,因为所有这些信息都在例如工具提示中(也许足以捕获工具提示数据)。
为了使这一点更清楚:
-如果你将鼠标悬停在变量上我想知道这个词是一个变量我也想知道这个变量的名称和类型。对于任何其他类型、接口等也是如此。
- 如果您将鼠标悬停在 'var' 关键字上,我想知道这个词是 'var' 关键字,我想知道它的类型。
-如果您将鼠标悬停在 class 内部的 'List[Domain.Example.TestClass]' 之类的泛型上,我想获得等于 'TestClass'
的类型
工具提示中的内容基本相同。
我正在尝试使用 'IQuickInfoSource',它允许我在光标下获取单词,但是我不知道如何获取任何其他数据。
我也尝试了 'IMouseProcessorProvider',但我得到了相同的结果,我能够获得当前单词但任何其他信息。
你能告诉我如何实现吗?或者至少给我指出正确的方向,因为很难找到任何关于 visual studio 扩展的适当文档。如果您需要更多信息,请询问。
提前致谢。
几个小时后,我实现了我想要的。如果有人会尝试做同样的事情,那么您可以在下面找到步骤。
我正在使用 '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);
}
}
要获取有关鼠标位置下令牌的信息,您需要(一般而言):
- 实施
IMouseProcessorProvider
以响应鼠标事件 - 使用
e.GetPosition(_view.VisualElement);
获取鼠标位置
- 获取鼠标在文本缓冲区中的相对位置。这有点困难,因为您需要减去滚动条的宽度等等。
- 获取流位置
- 从流位置获取 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。