如何在 VSIX 项目中操作位置导航

问题描述 投票:0回答:1

我正在开发一个VSIX项目来为vs2019制作插件,我创建了一个菜单命令,可以根据光标位置文本跳转到适当的代码位置。我使用

DTE.Find.Execute
接口来实现我的需求,这个功能可以正常运行, 但我发现执行这个命令后,View.Navigate Backward功能(vs2019的内置功能)出现了问题。无法跳回命令调用之前的代码位置,并且新旧位置之间存在很多不相关的代码位置。

我想知道如何解决这个问题?

主要代码如下:

bool GoToRegexJump(string originalText)
{
    string config = UtilsClass.GetRegexJumpConfig(Package);
    JArray array = JArray.Parse(config);
    string project = UtilsClass.GetSolutionSort(Package).ToString();
    foreach (var item in array)
    {
        string projects = item[Constants.USERSETTINGS_REGEX_JUMP_PROJECT].ToObject<string>();
        string files = item[Constants.USERSETTINGS_REGEX_JUMP_FILES].ToObject<string>();
        string[] allowProjects = projects.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
        string key = item[Constants.USERSETTINGS_REGEX_JUMP_KEY].ToObject<string>();
        bool matchCase = item[Constants.USERSETTINGS_REGEX_JUMP_MATCH_CASE].ToObject<bool>();

        if (allowProjects.Contains(project))
        {
            var match = Regex.Match(originalText, key);
            if (match.Success)
            {
                string pattern = item[Constants.USERSETTINGS_REGEX_JUMP_VALUE].ToObject<string>();
                for (int i = 0; i < match.Groups.Count; ++i)
                {
                    string value = match.Groups[i].Value;
                    value = Regex.Escape(value);
                    pattern = pattern.Replace($"${i}", value);
                }
                
                if (FindText(
                        pattern
                        , false
                        , vsFindTarget.vsFindTargetSolution, vsFindPatternSyntax.vsFindPatternSyntaxRegExpr
                        , false, matchCase, string.IsNullOrEmpty(files) ? "*.h;*.cpp" : files))
                {
                    return true;
                }
            }
        }
    }

    return false;
}

bool FindText(string text, bool backwards = false, vsFindTarget target = vsFindTarget.vsFindTargetCurrentDocument, vsFindPatternSyntax syntax = vsFindPatternSyntax.vsFindPatternSyntaxLiteral, bool matchWholeWord = false, bool matchCase = false, string filesOfType = "*.h;*.cpp", string searchPath = "")
{
    Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();

    var dte = Package.GetService<DTE, DTE2>();
    if (dte == null)
    {
        return false;
    }

    if (target == vsFindTarget.vsFindTargetCurrentDocument)
    {
        var textView = GetActiveTextView();
        if (textView == null)
        {
            return false;
        }
    }

    dte.Find.MatchCase = matchCase;
    dte.Find.MatchWholeWord = matchWholeWord;
    dte.Find.Action = vsFindAction.vsFindActionFind;
    dte.Find.SearchPath = searchPath;
    dte.Find.Target = target;
    dte.Find.Backwards = backwards;
    dte.Find.MatchInHiddenText = true;
    dte.Find.PatternSyntax = syntax;
    dte.Find.FindWhat = text;
    dte.Find.FilesOfType = filesOfType;

    var findResult = dte.Find.Execute();

    if (findResult == vsFindResult.vsFindResultFound)
    {
        return true;
    }

    if (UtilsClass.IsDebugMode(Package))
    {
        UtilsClass.PrintMessage(
            $"Found {dte.Find.FindWhat} Failed,SearchPath={dte.Find.SearchPath},FilesOfType={dte.Find.FilesOfType}。");
    }

    return false;
}
visual-studio vsix
1个回答
0
投票

我有一个 VS 插件,其中包含 VS 的自定义代码图,其中包括代码元素的自定义导航。我在将导航集成到 VS Navigate Backward 功能方面也遇到了很多困难。我尝试了很多东西,包括使用“转到”命令的 DTE 执行 API,但没有任何真正的帮助,直到我使用 Roslyn

VisualStudioWorkspace
的这个助手:
VisualStudioWorkspace.TryGoToDefinitionAsync()

我自己的问题中有描述: 如何导航到位于外部程序集中的符号定义

还有另一篇文章:Roslyn - 在 Visual Studio 扩展中导航到 SourceText

我不能保证它会解决您的问题,但它对我有很大帮助。现在 VS 中的自定义导航感觉就像是 VS 原生的,具有很酷的功能,例如:

  • 与向后/向前导航 VS 功能集成
  • 当用户尝试导航到分部类时,将打开一个包含所有分部类声明的对话框
  • 当用户尝试导航到外部依赖项(例如引用的 DLL)中定义的内容时,根据 VS 设置,导航会将他带到生成的元数据或反编译的源。
© www.soinside.com 2019 - 2024. All rights reserved.