1

I'm trying to create a new macro that takes the currently selected text and puts curly braces around it (after making a newline), while, of course, indenting as needed.

So, for example, if the user selects the code x = 0; and runs the macro in the following code:

if (x != 0) x = 0;

It should turn into:

if (x != 0) 
{
    x = 0;
}

(Snippets don't help here, because this also needs to work for non-supported source code.)

Could someone help me figure out how to do the indentation and the newlines correctly? This is what I have:

Public Sub NewScope()
    Dim textDoc As TextDocument = _
                CType(DTE.ActiveDocument.Object("TextDocument"), TextDocument)
    textDoc.???
End Sub

but how do I figure out the current indentation and make a newline?

user541686
  • 205,094
  • 128
  • 528
  • 886
  • ...really? I can't believe I got a tumbleweed badge for this, lol... it seems rather simple. Hope the bounty helps. :) – user541686 Jan 21 '11 at 22:23
  • I know this doesn't answer your question, but with Resharper, in case someone is wondering - this is done by Ctrl+E+U, 7 (Surround With {}) – Omer Raviv Jan 27 '11 at 23:12

2 Answers2

2
Sub BracketAndIndent()
    Dim selection = CType(DTE.ActiveDocument.Selection, TextSelection)

    ' here's the text we want to insert
    Dim text As String = selection.Text

    ' bracket the selection;
    selection.Delete()

    ' remember where we start
    Dim start As Integer = selection.ActivePoint.AbsoluteCharOffset

    selection.NewLine()
    selection.Text = "{"
    selection.NewLine()
    selection.Insert(text)
    selection.NewLine()
    selection.Text = "}"

    ' this is the position after the bracket
    Dim endPos As Integer = selection.ActivePoint.AbsoluteCharOffset

    ' select the whole thing, including the brackets
    selection.CharLeft(True, endPos - start)

    ' reformat the selection according to the language's rules
    DTE.ExecuteCommand("Edit.FormatSelection")
End Sub
Steve Cooper
  • 20,542
  • 15
  • 71
  • 88
  • Ah, thank you, it does exactly what I wanted. Another question (although this one isn't as important): Is there a way to do this *without* modifying the undo buffer? – user541686 Jan 28 '11 at 01:25
  • 1
    I'm guessing you don't actually want to leave the undo buffer untouched. Instead, you want to be able to undo the effects of your macro in one step (instead of hitting ctrl+z for every text action your macro performed). In that case, open an [UndoContext](http://msdn.microsoft.com/en-us/library/envdte.undocontext%28v=VS.90%29.aspx) when your macro starts, and close it before it exits. Then you can undo your macro by hitting ctrl+z just once. – Stuart Berg Jan 03 '12 at 21:31
0

textDoc.Selection.Text = "\n{\n\t" + textDoc.Selection.Text + "\n}\n"

Of course the amount of \t before the { and } and Selection depend on the current indention.

Since there is a difference between selected Text and Document data, it's hard to find out where the cursor is within the document's data (at least in Outlook it is).

The only way I figured out how to do this in Outlook is to actually move the selection backwards until I got text that I needed, but that resulted in undesirable effects.

Try taking the selection start, and using that position in the document text, looking at that line and getting the amount of tabs.

I would think there wouldn't be formatting characters in VStudio.

Lee Louviere
  • 5,162
  • 30
  • 54
  • The question literally stated, " *how do I figure out the current indentation and make a newline* "? Sorry, but your answer doesn't really tell me how to figure out the current indentation and make a newline indented the same amount. :( – user541686 Jan 24 '11 at 22:13