visual studio – How to manipulate position navigation in VSIX project


I am working on a VSIX project to produce plugins for vs2019, I have created a menu command that can jump to the appropriate code position based on the cursor position text. I Use DTE.Find.Execute interface to implement my requirements, this function can run normally,
but I found that after executing this command, there was a problem with the View.Navigate Backward function (The built-in function of vs2019). It could not jump back to the code position before the command call, and there were many irrelevant code positions between the new and old positions.

I want to know how to solve this problem ?

Here is the main code:

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;
}

Leave a Reply

Your email address will not be published. Required fields are marked *