Sergio and the sigil

Unescape my Strings

Posted by Sergio on 2008-05-07

Since I started using Visual Studio 2005 and now 2008 it bugs me that strings in the debug windows (Immediate, Watch, Locals, Autos, etc) are automatically escaped in C# syntax (well, at least in C# projects.)

Let's assume we are writing some code that produces HTML (or XML, or SQL, or JSON, etc) where the text identation is important for understanding the contents. If we find ourselves in the middle of debugging that code and check the value of a variable containing such type of text, here's what we would see.

System.Diagnostics.Debug.WriteLine(html);
Console.WriteLine(html); // BREAKPOINT HERE
Console.ReadLine();

The Immediate window becomes less useful. The line breaks below do not exist in the Immediate window, I added them here for clarity.

?html
"<html>\r\n\t<head>\r\n\t\t<title>Monthly Report</title>\r\n\t\t<style>
\r\n\t\t\t.results td {color:#999;}\r\n\t\t\t/*etc*/\r\n\t\t</style>\r
\n\t</head>\r\n\t<body>\r\n\t\t<h1>Report for April 2008</h1>\r\n\t\t<d
iv id=\"content\">\r\n\t\t\t<p>\r\n\t\t\t\ttext goes here...\r\n\t\t\t<p
>\r\n\t\t</div>\r\n\t</body>\r\n</html>"

Same problem in the Locals or Autos windows, but there at least you can use the visualizers.

Too many clicks for me, though. Besides, the visualizers are modal windows and that makes it harder when you want to compare things.

If you happen to know how to revert to the old behavior of keeping the text format, please let me know. Until I find the right way (or at least a better way) I'm using a little macro to output any selected escaped text, unescaped to a new output pane.

To create the macro:

  • View » Other Windows » Macro Explorer
  • Right-click "My Macros" » New Module
  • Call the new module Unescape
  • Add the following sub
Public Module Unescape
  Public Sub UnescapeText()
    Dim winName As String = "Unescaped"
    Dim win As Window
    Dim output As OutputWindow
    Dim pane As OutputWindowPane = Nothing

    If DTE.ActiveWindow IsNot Nothing AndAlso _
      DTE.ActiveWindow.Selection IsNot Nothing Then

      Dim text As String = DTE.ActiveWindow.Selection.Text

      If Not String.IsNullOrEmpty(text) Then

        text = text.Replace("\t", vbTab) _
          .Replace("\r\n", vbCrLf) _
          .Replace("\n", vbCrLf) _
          .Replace("\r", vbCrLf) _
          .Replace("\""", """")

        win = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
        output = win.Object

        For Each p As OutputWindowPane In output.OutputWindowPanes
          If p.Name = winName Then
            pane = p
            Exit For
          End If
        Next
        If pane Is Nothing Then _
          pane = output.OutputWindowPanes.Add(winName)

        win.Activate()
        pane.Activate()
        pane.OutputString(text)
      End If
    End If
  End Sub
End Module

I made a shortcul for this macro:

  • Tools » Options » Environment » Keyboard
  • Show commands containing: unescape
  • Select the macro when it gets listed
  • Add a Global shortcut, I used Ctrl+Alt+U

Now if I select the escaped text in the Immediate window and press the macro shortcut, I get the following:

If I keep selecting other escaped texts and unescaping them, they'll just be appended to that output, making it possible to do some visual inspection or comparisons.