Visual Studio-вставка многострочных выражений в окно просмотра во время отладки

во время отладки в Visual Studio, как я могу вставить многострочные выражения в окно просмотра, так что каждая строка не разбивается на отдельное недопустимое выражение просмотра. Это действительно расстраивает, потому что у меня много выражений, охватывающих несколько строк, которые мне нужно смотреть. Обратите внимание, что окно Pin to Source и Immediate не работает для отслеживания нескольких значений из многих мест исходного кода.

например

PyFunc1(Py.kw("var1", var1),
        Py.kw("var2", var2))

ломается кому:

PyFunc1(Py.kw("var1", var1),

и

Py.kw("var2", var2))

2 ответов


Repro

Я не думаю, что это "по дизайну", его просто недоступно "из коробки".

Я согласен, было бы лучше поведение для многострочных вызовов, которые будут добавлены в окно просмотра с использованием линейных Терминаторов вместо новых строк:

enter image description here


исследования

Я нашел этот аналогичный вопрос с несколькими "обходными путями" на выбор: многострочное окно просмотра в Visual Studio 2010?

Я нашел этот комментарий в форумы MSDN инженером MSFT:

боюсь, что это не поддерживается, мы часто редактируем их один за другим. Возможно, вы могли бы отправить этот запрос функции:http://visualstudio.uservoice.com/forums/121579-visual-studio


сверните собственную надстройку Visual Studio

так что я сам попробовал, это ни в коем случае рабочий код, но он показывает вам, как сделать это:

(кликните по картинке для увеличения)

enter image description here

namespace AddinMultiLineWatch
{
public class Connect : IDTExtensibility2, IDTCommandTarget
{
    //ADD THESE MEMBER VARIABLES
    //private DebuggerEvents _debuggerEvents = null;
    //private _dispDebuggerEvents_OnEnterBreakModeEventHandler DebuggerEvents_OnEnterBreakMode;
    private Window _watchWindow = null;
    private CommandEvents _objCommandEvents;
    private bool _isRecursive = false;
    public Connect()
    {
    }

    public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
    {
        _applicationObject = (DTE2)application;
        _addInInstance = (AddIn)addInInst;

        //SET THE MEMBER VARIABLES
        //_debuggerEvents = _applicationObject.Events.DebuggerEvents;
        //_debuggerEvents.OnEnterBreakMode += new _dispDebuggerEvents_OnEnterBreakModeEventHandler(BreakHandler);
        //var watchWindow = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindWatch);
        _objCommandEvents = _applicationObject.Events.CommandEvents;
        _objCommandEvents.BeforeExecute += new _dispCommandEvents_BeforeExecuteEventHandler(BeforeExecute);

        if(connectMode == ext_ConnectMode.ext_cm_UISetup)
        {
            object []contextGUIDS = new object[] { };
            Commands2 commands = (Commands2)_applicationObject.Commands;
            string toolsMenuName = "Tools";

            Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = ((Microsoft.VisualStudio.CommandBars.CommandBars)_applicationObject.CommandBars)["MenuBar"];
ar:
            CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
            CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

            try
            {
                Command command = commands.AddNamedCommand2(_addInInstance, "AddinMultiLineWatch", "AddinMultiLineWatch", "Executes the command for AddinMultiLineWatch", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);

                if((command != null) && (toolsPopup != null))
                {
                    command.AddControl(toolsPopup.CommandBar, 1);
                }
            }
            catch(System.ArgumentException)
            {
            }
        }
    }

    //ADD THIS METHOD TO INTERCEPT THE DEBUG.ADDWATCH COMMAND
    public void BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
    {
        EnvDTE.Command objCommand = default(EnvDTE.Command);
        try
        {
            objCommand = _applicationObject.Commands.Item(Guid, ID);
        }
        catch (Exception ex)
        {
        }

        if ((objCommand != null))
        {
            if (objCommand.Name == "Debug.AddWatch")
            {
                //if (_isRecursive) return;
                //_isRecursive = true;
                TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;
                //TODO make selection goto next semi-colon/Line Terminator...
                var selText = selection.Text;  

                if (string.IsNullOrEmpty(selText)) return;   
                //Only intercept multi-line Add Watch commands                    
                if (selText.Contains(Environment.NewLine))
                {
                  //THE BLACK MAGIC: make it fit in one line! lol
                  selText = selText.Replace(Environment.NewLine, string.Empty);              
                  //THIS CALL IS RECURSIVE, I'LL LEAVE IT TO THE READER AS AN EXERCISE TO SOLVE..
                _applicationObject.ExecuteCommand("Debug.AddWatch", selText);
               }
            }
        }
    }
  1. создайте новый проект > другие типы проектов > расширяемость > надстройка Visual Studio > назовите его AddinMultiLineWatch

  2. пройти через мастера

  3. добавьте код выше для подключения.cs class-см. мои / / комментарии в верхнем регистре с тем, что нужно добавлять.

  4. поставить точку останова на строку TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;

  5. нажмите F5, и новый экземпляр VS запустится > выберите Новый проект > консольное приложение > назовите его TestMultilineAddWatch

  6. в программе.cs консольного приложения, укажите код вызова более 2 строк и поставить точку останова на нем, как показано на скриншоте, например:

    Add(1,            //Breakpoint here and select both lines
            2);
    }
    
    static int Add(int i, int j)
    {
        return i + j;
    }
    
  7. F5 в решении TestMultilineAddWatch и когда код контрольные остановки на точке останова > выберите / выделите две строки Add(1, \r\n 2) > Правой Кнопкой Мыши > добавить

  8. нажмите кнопку Добавить Часы в контекстном меню отладки vs IDE заставляет решение VS AddinMultiLineWatch перехватывать вызов и активировать, останавливаясь на точке останова.... где вы увидите черная магия of замена многострочного кода в одной строке отправлено в дозор Окно.

вызов команды Visual Studio EXEC делает этот метод рекурсивным, если вы отладите его, выйдя из рекурсии вручную, вы увидите результаты в соответствии с моим скриншотом.

счастливой отладки!


вы можете сделать это с помощью autohotkey и привязки пользовательского ключа (например, Alt+Shift+V)

!+v означает Alt + Shift + V

макрос ниже: Если в команду devenv.exe, и вы нажимаете Alt + Shift+V, редактируете содержимое буфера обмена, удаляете /r / n и заменяете их ничем, затем нажимаете Ctrl+V, чтобы вставить

я протестировал это вырезание и вставку в текстовый документ в visual studio.

#IfWinActive ahk_exe devenv.exe
!+v::
FixString = %clipboard%
StringReplace, FixString, FixString,`r`n,,A
Clipboard := FixString
Send, ^v