这是可以做到的。这里有一个解决方案(尽管有点老套):使用F1帮助上下文。为了使F1帮助生效,Visual Studio将当前选择或插入点的完全限定类型名称推入一个名为“F1帮助上下文”的名称/值对包中。Visual Studio SDK中有公共API用于查询F1帮助上下文的内容。
-
-
-
重新启动Visual Studio以获取更改
-
这是注册表项:
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Dynamic Help]
"Display Debug Output in Retail"="YES"
让这更容易的诀窍是:Visual Studio可以将关键字标记为区分大小写或不区分大小写。AFAIK是Visual Studio中唯一注入区分大小写关键字的部分,它是区分大小写语言(C#、C++)的代码编辑器,用于响应代码上下文。因此,如果你将所有关键字过滤为区分大小写的关键字,你就知道你在看代码。
不幸的是,如果插入点位于语言关键字之上,C#编辑器还会将语言关键字(而不仅仅是标识符)推送到帮助上下文中。因此,您需要筛选出语言关键字。有两种方法可以做到这一点。你可以简单地尝试在类型系统中查找它们,由于它们不是有效的类型名称(尤其是VS对它们的处理方式,例如字符串关键字的“string_CSharpKeyword”),你可能会默默地失败。或者,您可以检测到缺少点,并假设它不是类型名称。或者,您可以检测_CSharpKeyword后缀,并希望VS团队不要更改它。:-)
另一个潜在的问题是仿制药。您将从VS获得的泛型类型的类型名称如下:
System.Collections.Generic.List`1
System.Collections.Generic.List`1.FindAll.
此外,在ASP。NET MVC。ASPX文件,页面上有C#代码和其他区分大小写的代码(例如javascript)。在这种情况下,您还需要查看属性。除了关键字,Help Context还有“属性”,即描述当前上下文的名称/值对。例如,devlang=csharp是一个属性。下面的代码也可以用来提取属性。你需要进行实验,找出要查找的正确属性,这样你就不会对javascript或其他奇怪的代码采取行动。
不管怎样,现在您已经了解了(或者至少已经接触过!)所有的注意事项,这里有一些代码可以从帮助上下文中提取区分大小写的关键字(如果存在),以及其余的名称/值对。(关键字只是名称为“关键字”的名称/值对)。
请记住,此代码需要Visual Studio SDK(而不仅仅是常规的VS安装)才能构建,才能获得Microsoft。Visual Studio。壳牌。微软互操作公司。Visual Studio。壳牌和微软。Visual Studio。好啊。互操作命名空间(您需要将其作为引用添加到插件项目中)。
using System;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.CommandBars;
using System.Resources;
using System.Reflection;
using System.Globalization;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.OLE.Interop;
using System.Collections.Generic;
public class HelpAttribute
{
public string Name;
public string Value;
public VSUSERCONTEXTPRIORITY Priority;
public VSUSERCONTEXTATTRIBUTEUSAGE Usage;
}
public class HelpContext2 : List<HelpAttribute>
{
public static HelpContext2 GetHelpContext(DTE2 dte)
{
// Get a reference to the current active window (presumably a code editor).
Window activeWindow = dte.ActiveWindow;
// make a few gnarly COM-interop calls in order to get Help Context
Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp = (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)activeWindow.DTE;
Microsoft.VisualStudio.Shell.ServiceProvider serviceProvider = new Microsoft.VisualStudio.Shell.ServiceProvider(sp);
IVsMonitorUserContext contextMonitor = (IVsMonitorUserContext)serviceProvider.GetService(typeof(IVsMonitorUserContext));
IVsUserContext userContext;
int hresult = contextMonitor.get_ApplicationContext(out userContext);
HelpContext2 attrs = new HelpContext2(userContext);
return attrs;
}
public HelpContext2(IVsUserContext userContext)
{
int count;
userContext.CountAttributes(null, 1, out count);
for (int i = 0; i < count; i++)
{
string name, value;
int priority;
userContext.GetAttributePri(i, null, 1, out priority, out name, out value);
VSUSERCONTEXTATTRIBUTEUSAGE[] usageArray = new VSUSERCONTEXTATTRIBUTEUSAGE[1];
userContext.GetAttrUsage(i, 1, usageArray);
VSUSERCONTEXTATTRIBUTEUSAGE usage = usageArray[0];
HelpAttribute attr = new HelpAttribute();
attr.Name = name;
attr.Value = value;
attr.Priority = (VSUSERCONTEXTPRIORITY)priority;
attr.Usage = usage; // name == "keyword" ? VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Lookup : VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Filter;
this.Add(attr);
}
}
public string CaseSensitiveKeyword
{
get
{
HelpAttribute caseSensitive = Keywords.Find(attr =>
attr.Usage == VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_LookupF1_CaseSensitive
|| attr.Usage == VSUSERCONTEXTATTRIBUTEUSAGE.VSUC_Usage_Lookup_CaseSensitive
);
return caseSensitive == null ? null : caseSensitive.Value;
}
}
public List<HelpAttribute> Keywords
{
get
{
return this.FindAll(attr=> attr.Name == "keyword");
}
}
}