Hotkeys for Previous and Next call stack frames in Visual Studio

烂漫一生 提交于 2019-12-02 19:11:30

I wrote 2 macros to gain it: PreviousStackFrame and NextStackFrame and assigned shortcuts to

Function StackFrameIndex(ByRef aFrames As EnvDTE.StackFrames, ByRef aFrame As EnvDTE.StackFrame) As Long
    For StackFrameIndex = 1 To aFrames.Count
        If aFrames.Item(StackFrameIndex) Is aFrame Then Exit Function
    Next
    StackFrameIndex = -1
End Function

Sub NavigateStack(ByVal aShift As Long)
    If DTE.Debugger.CurrentProgram Is Nothing Then
        DTE.StatusBar.Text = "No program is currently being debugged."
        Exit Sub
    End If

    Dim ind As Long = StackFrameIndex(DTE.Debugger.CurrentThread.StackFrames, DTE.Debugger.CurrentStackFrame)
    If ind = -1 Then
        DTE.StatusBar.Text = "Stack navigation failed"
        Exit Sub
    End If

    ind = ind + aShift
    If ind <= 0 Or ind > DTE.Debugger.CurrentThread.StackFrames.Count Then
        DTE.StatusBar.Text = "Stack frame index is out of range"
        Exit Sub
    End If

    DTE.Debugger.CurrentStackFrame = DTE.Debugger.CurrentThread.StackFrames.Item(ind)
    DTE.StatusBar.Text = "Stack frame index: " & ind & " of " & DTE.Debugger.CurrentThread.StackFrames.Count
End Sub

Sub PreviousStackFrame()
    NavigateStack(1)
End Sub

Sub NextStackFrame()
    NavigateStack(-1)
End Sub

I have solved this problem with AutoHotkey. I made this a few months ago. Suppose you wanted to use Control+1 and Control+2 and that Control+Alt+C is bound to showing the Call Stack window:

^1::SendInput !^c{down}{enter}
^2::SendInput !^c{up}{enter}

It seems to work pretty well. If you aren't already using AutoHotkey to show Visual Studio who's boss, please give it a shot. Your question indicates that you would benefit greatly from it. It's a game changer. Good luck.

I don't think theres an explict next-frame / prev-frame key binding but heres what I do.

CTRL-ALT-C is already bound to "Debug.CallStack" This will focus you in the Call Stack Tool Window

Once focused in the Callstack window... Up & Down arrows will move you through the call stack frames

I've then bound

CTRL-C, CTRL-S to "DebuggerContextMenus.CallStackWindow.SwitchToFrame" and CTRL-C, CTRL-C to "DebuggerContextMenus.CallStackWindow.SwitchToCode"

both of which will take you back into the code window at the particular frame.

Hope that helps.

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

Look in Tools->Options->Environment->Keyboard. Enter "stack" or "frame" and related menus will appear. It seems that there's no next and previous call-stack frame.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!