admin管理员组文章数量:1122846
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;
}
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;
}
Share
Improve this question
edited Nov 23, 2024 at 2:28
hchlqlz
asked Nov 23, 2024 at 2:20
hchlqlzhchlqlz
234 bronze badges
1 Answer
Reset to default 0I have a VS plugin with a custom Code Map for VS which includes custom navigation to code elements. I also struggled a lot with an integration of my navigation into VS Navigate Backward functionality. I tried many things including DTE ExecuteCommand
API with the "Go To" command but nothing really helped until I used this helper from the Roslyn VisualStudioWorkspace
:
VisualStudioWorkspace.TryGoToDefinitionAsync()
.
It is described in my own question: How to navigate to a definition of a Symbol located in the external assembly
And also in another one: Roslyn - Navigate to SourceText in a Visual Studio extension
I can't guarantee that it will solve your issue, but it greatly helped me. Now custom navigation in VS feels like it is native to VS with cool features like:
- Integration with Navigate Backward/Forward VS functionality
- When user tries to navigate to a partial class, a dialog with all partial class declarations is opened
- When user tries to navigate to something defined in an external dependency (a referenced DLL, for example), depending of VS settings the navigation takes him to the generated metadata or decompiled sources.
本文标签: visual studioHow to manipulate position navigation in VSIX projectStack Overflow
版权声明:本文标题:visual studio - How to manipulate position navigation in VSIX project - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736300017a1930666.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论