Hotkeys for Previous and Next call stack frames in Visual Studio

前端 未结 5 947
温柔的废话
温柔的废话 2021-02-01 20:09

Visual Studio gives many navigation hotkeys: F8 for next item in current panel (search results, errors ...), Control+K, N for bookmar

5条回答
  •  旧时难觅i
    2021-02-01 20:52

    Huge thanks to @Oleg Svechkarenko for his answer that gave me a starting point in crafting this solution. Since modern versions of Visual Studio no longer have official macro support, this should drop in for those who use the Visual Commander plugin, but probably can be easily adapted for any other macro extension.

    Here is the code for the command, I created one for navigating up the call stack and one for navigating down with the same code except the parameter passed to MoveStackIndex(), then bound keyboard shortcuts to them:

    using EnvDTE;
    using EnvDTE80;
    using System;
    
    public class C : VisualCommanderExt.ICommand
    {
        enum MoveDirection
        {
            Up,
            Down,
        }
    
        private bool IsValidFrame(StackFrame frame)
        {
            string language = frame.Language;
    
            bool result = (language == "C#"  || 
                           language == "C++" || 
                           language == "VB"  || 
                           language == "Python");
    
            return result;
        }
    
        private void MoveStackIndex(EnvDTE80.DTE2 DTE, MoveDirection direction)
        {
            StackFrame currentFrame = DTE.Debugger.CurrentStackFrame;
    
            bool foundTarget = false;
            bool pastCurrent = false;
    
            StackFrame lastValid = null;
            foreach (StackFrame frame in DTE.Debugger.CurrentThread.StackFrames)
            {
                bool isCurrent = frame == currentFrame;
    
                if (direction == MoveDirection.Down)
                {
                    if (isCurrent)
                    {
                        if (lastValid == null)
                        {
                            // No valid frames below this one
                            break;
                        }
                        else
                        {
                            DTE.Debugger.CurrentStackFrame = lastValid;
                            foundTarget = true;
                            break;                      
                        }
                    }
                    else
                    {
                        if (IsValidFrame(frame))
                        {
                            lastValid = frame;
                        }
                    }
                }
    
                if (direction == MoveDirection.Up && pastCurrent)
                {
                    if (IsValidFrame(frame))
                    {
                        DTE.Debugger.CurrentStackFrame = frame;
                        foundTarget = true;
                        break;
                    }               
                }
    
                if (isCurrent)
                {
                    pastCurrent = true;
                }
            }
    
            if (!foundTarget)
            {
                DTE.StatusBar.Text = "Failed to find valid stack frame in that direction.";
            }
        }
    
        public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package) 
        {
            if (DTE.Debugger.CurrentProgram == null)
            {
                DTE.StatusBar.Text = "Debug session not active.";
            }
            else
            {
                // NOTE: Change param 2 to MoveDirection.Up for the up command
                MoveStackIndex(DTE, MoveDirection.Down);
            }
        }
    }
    

提交回复
热议问题