我正在为自定义脚本语言实现 Visual Studio 语言服务。我设法实现了语法高亮、错误检查、代码完成和“转到定义”。我无法弄清楚如何连接到“查找所有参考”菜单选项(或者甚至在此时显示它)。
谁能指出我在 Visual Studio 中为自定义语言实现“查找所有引用”功能的有用资源? 我试过谷歌搜索有关它的任何信息,但我似乎找不到任何东西。
我正在为自定义脚本语言实现 Visual Studio 语言服务。我设法实现了语法高亮、错误检查、代码完成和“转到定义”。我无法弄清楚如何连接到“查找所有参考”菜单选项(或者甚至在此时显示它)。
谁能指出我在 Visual Studio 中为自定义语言实现“查找所有引用”功能的有用资源? 我试过谷歌搜索有关它的任何信息,但我似乎找不到任何东西。
首先,可以在多个位置调用 Find All References。主要的有:
其他包括:
在理想的实现中,您将拥有一个IVsSimpleLibrary2
将您的语言支持集成到类视图和对象浏览器窗口中的实现。Find All References 的实现IVsFindSymbol
以 Visual Studio 提供的接口为中心。您的代码处理IVsSimpleLibrary2.GetList2
.
确保您的库功能包括_LIB_FLAGS2.LF_SUPPORTSLISTREFERENCES
.
在您的处理程序中IVsSimpleLibrary2.GetList2
,您对以下所有情况都为真的情况感兴趣。
pobSrch
是一个长度为 1 的非空数组。我将假设第一个元素分配给criteria
这些条件的其余部分的局部变量。criteria.eSrchType == VSOBSEARCHTYPE.SO_ENTIREWORD
criteria.grfOptions
有国旗_VSOBSEARCHOPTIONS.VSOBSO_LOOKINREFS
criteria.grfOptions
有国旗_VSOBSEARCHOPTIONS.VSOBSO_CASESENSITIVE
当满足上述条件时,返回一个IVsSimpleObjectList2
实现,其子项是 Find All References 命令的延迟计算结果。
在您的ViewFilter.QueryCommandStatus
实现中,您何时guidCmdGroup == VSConstants.GUID_VSStandardCommandSet97
需要nCmdId == VSStd97CmdID.FindReferences
返回OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED
.
nCmdId
与前面提到的相同。从 Visual Studio 2008 开始,此不匹配已得到纠正,此后不再使用该点。VSStd2KCmdID.FindReferences
guidCmdGroup
VSStd2KCmdID.FindReferences
覆盖ViewFilter.HandlePreExec
上面列出的命令 GUID 和 ID 的情况,并针对该情况执行以下代码:
HandleFindReferences();
return true;
添加以下扩展方法类:
public static class IVsFindSymbolExtensions
{
public static void DoSearch(this IVsFindSymbol findSymbol, Guid symbolScope, VSOBSEARCHCRITERIA2 criteria)
{
if (findSymbol == null)
throw new ArgumentNullException("findSymbol");
VSOBSEARCHCRITERIA2[] criteriaArray = { criteria };
ErrorHandler.ThrowOnFailure(findSymbol.DoSearch(ref symbolScope, criteriaArray));
}
}
将以下方法添加到您的ViewFilter
类中:
public virtual void HandleFindReferences()
{
int line;
int col;
// Get the caret position
ErrorHandler.ThrowOnFailure( TextView.GetCaretPos( out line, out col ) );
// Get the tip text at that location.
Source.BeginParse(line, col, new TokenInfo(), ParseReason.Autos, TextView, HandleFindReferencesResponse);
}
// this can be any constant value, it's just used in the next step.
public const int FindReferencesResults = 100;
void HandleFindReferencesResponse( ParseRequest req )
{
if ( req == null )
return;
// make sure the caret hasn't moved
int line;
int col;
ErrorHandler.ThrowOnFailure( TextView.GetCaretPos( out line, out col ) );
if ( req.Line != line || req.Col != col )
return;
IVsFindSymbol findSymbol = CodeWindowManager.LanguageService.GetService(typeof(SVsObjectSearch)) as IVsFindSymbol;
if ( findSymbol == null )
return;
// TODO: calculate references as an IEnumerable<IVsSimpleObjectList2>
// TODO: set the results on the IVsSimpleLibrary2 (used as described below)
VSOBSEARCHCRITERIA2 criteria =
new VSOBSEARCHCRITERIA2()
{
dwCustom = FindReferencesResults,
eSrchType = VSOBSEARCHTYPE.SO_ENTIREWORD,
grfOptions = (uint)_VSOBSEARCHOPTIONS2.VSOBSO_LISTREFERENCES,
pIVsNavInfo = null,
szName = "Find All References"
};
findSymbol.DoSearch(new Guid(SymbolScopeGuids80.All), criteria);
}
更新您的IVsSimpleLibrary2.GetList2
. 当搜索条件的dwCustom
值设置为FindReferencesResults
时,您无需在类视图或对象浏览器节点上计算 Find All References 命令的结果,您只需返回IVsSimpleObjectList2
包装先前由您的HandleFindReferencesResponse
方法计算的结果的 。