Question

If I was to have:

/// <summary>
/// My summary
/// </summary>
/// <param name='args'></param>

on the clipboard pasted it on top of the method static void Main(string[] args), it will look like:

class Program
{
    /// <summary>
    /// This is my summary
    /// </summary>
    /// <param name='args'></param>
    static void Main(string[] args)
    { 
    }
}

Note: The text I had on the clipboard had no indentation (4 white spaces on the left). When I pasted it, Visual Studio was able to figure out that it needed indentation.

I would like to do the same thing with a macro. I do not want to use the clipboard as I have the text I want to insert in a variable (myText). I have something like:

Sub TemporaryMacro()

    Dim myText As String = "/// <summary>" _
    & vbCrLf & "/// My summary" _
    & vbCrLf & "/// </summary>" _
    & vbCrLf & "/// <param name='args'></param>"

    DTE.ActiveDocument.Selection.Text = myText

End Sub

When I run that macro I end up with:

class Program
{

    /// <summary>
    ///  <summary>
    ///  /// My summary
    ///  /// </summary>
    ///  /// <paramref name=" name='args'></param>"/></summary>
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {

    }
}

Note: I do get a different result.


I have also tried:

Public Module RecordingModule
    Sub TemporaryMacro()

        Dim myText As String = "/// <summary>" _
        & vbCrLf & "/// My summary" _
        & vbCrLf & "/// </summary>" _
        & vbCrLf & "/// <param name='args'></param>"

        DTE.ActiveDocument.Selection.Insert(myText)

    End Sub
End Module

which results in:

class Program
{

    /// <summary>
/// My summary
/// </summary>
/// <param name='args'></param>
    static void Main(string[] args)
    {

    }
}

I know I can place myText on the clipboard and then paste it. That does not make sense though. How can I achieve the same behavior as if I where pasting myText without having it to place it on the clipboard?

Était-ce utile?

La solution 2

Finally found the solution:

Dim myText As String = "/// <summary>" _
     & vbCrLf & "/// My summary" _
     & vbCrLf & "/// </summary>" _
     & vbCrLf & "/// <param name='args'></param>"

DTE.ActiveDocument.Selection.Insert(myText)

' how many characters where inserted?
' Trying myText.Length gives incorrect results because visual studio counts \r\n as one character so we 
' use the regex \r\n|. to try to find first \r\n as one match and any other character as another match
Dim insertLength As Integer = System.Text.RegularExpressions.Regex.Matches(myText, "(?>\r\n|.)").Count

' select the text that was just inserted
DTE.ActiveDocument.Selection.CharLeft(True, insertLength)

' here comes the magic!
DTE.ActiveDocument.Selection.SmartFormat()

Edit

I am making this edit to ask why this answer reserved down votes. If you refer to the question title it asks: Visual studio macro to insert text like when pasting when you paste text it maters where the cursor is located! I do not have to search for static void Main(string[] args) also I up voted the other answer cause I appreciate the help. If I would have known the answer earlier I would have turn this question into a bounty.

Lastly the other solution does not work correclty... run that macro when I have comments at the top of the page and it does not work. It is helpful that's why I up voted!

Autres conseils

Have you tried this (simply adding your tabs/indentation to the code you've already tried)?

Public Module RecordingModule
    Sub TemporaryMacro()

        Dim myText As String = "/// <summary>" _
        & vbCrLf & vbTab &  "/// My summary" _
        & vbCrLf & vbTab &  "/// </summary>" _
        & vbCrLf & vbTab &  "/// <param name='args'></param>"

        DTE.ActiveDocument.Selection.Insert(myText)

    End Sub
End Module

This indentation won't work as-is for deeper nesting, however, unless you add more & vbTab &s.


Also, instead of using the current selection (meaning you have to have a cursor placed in your document), have your tried placing the text in the body relative to a specific line of text (static void Main(string[] args) in this case)?

You noted in your own answer that this specific string is not always needed, but the placement of the cursor is used instead. I was merely trying to point out that this was an option. If you change searchText in the code below, you can put your inserted text pretty much wherever you want. This can also be changed to look for the text at the cursor.

Something along the lines of this (untested) code:

Dim objTextDoc As TextDocument
Dim objEditPt As EditPoint
Dim objMovePt As EditPoint
Dim docText As String
Dim docNewText As String

Dim myText As String = "/// <summary>" _
    & vbCrLf & vbTab &  "/// My summary" _
    & vbCrLf & vbTab &  "/// </summary>" _
    & vbCrLf & vbTab &  "/// <param name='args'></param>"

Dim searchText As String = "static void Main(string[] args)"

objTextDoc = DTE.ActiveDocument.Object("TextDocument")
objEditPt = objTextDoc.StartPoint.CreateEditPoint
objMovePt = objTextDoc.StartPoint.CreateEditPoint

' Get all text of active document
docText = objEditPt.GetText(objTextDoc.EndPoint)

objEditPt.StartOfDocument()
objMovePt.EndOfDocument()

' Set string as the new intended body of the text, inserting myText just above the Main line
docNewText = docText.Substring(0, InStr(docText, searchText) - 1) & myText & docText.Substring(docText.Length() - InStr(docText, searchText) + searchText.Length())

objEditPt.ReplaceText(objMovePt, docNewText, vsEPReplaceTextOptions.vsEPReplaceTextAutoformat)

I believe that vsEPReplaceTextOptions.vsEPReplaceTextAutoformat (not confirmed) will auto-indent your code for you as well.

(See here for more info/ideas)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top