Visual Studio макрос для вставки текста, как при вставке

Если бы я должен был:

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

в буфер обмена наклеил его поверх метода static void Main(string[] args), это будет выглядеть так:

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

Примечание: текст, который я имел в буфере обмена, не имел отступов (4 пробела слева). Когда я вставил его, Visual Studio смогла выяснить, что он требует отступов.

Я хотел бы сделать то же самое с макросом. Я не хочу использовать буфер обмена, так как у меня есть текст, который я хочу вставить в переменную (myText). У меня есть что-то вроде:

Sub TemporaryMacro()

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

    DTE.ActiveDocument.Selection.Text = myText

End Sub

Когда я запускаю этот макрос, я получаю:

class Program
{

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

    }
}

Примечание: я получаю другой результат.


Я также попробовал:

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

что приводит к:

class Program
{

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

    }
}

Я знаю, что могу поставить myText в буфер обмена, а затем вставьте его. Это не имеет смысла, хотя. Как я могу добиться того же поведения, как если бы я где-то вставлять myText не имея его, чтобы поместить его в буфер обмена?

2 ответа

Решение

Наконец-то нашли решение:

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()

редактировать

Я делаю это изменение, чтобы спросить, почему этот ответ зарезервирован вниз. Если вы ссылаетесь на заголовок вопроса, он спрашивает: Visual studio macro to insert text like when pasting когда вы вставляете текст, он имеет значение, где находится курсор! Мне не нужно искать static void Main(string[] args) Я также проголосовал за другой ответ, потому что я ценю помощь. Если бы я знал ответ раньше, я бы превратил этот вопрос в награду.

Наконец, другое решение не работает корректно... запустите этот макрос, когда у меня есть комментарии в верхней части страницы, и он не работает. Это полезно, поэтому я проголосовал!

Вы пробовали это (просто добавляя свои вкладки / отступы к коду, который вы уже пробовали)?

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

Однако этот отступ не будет работать как есть для более глубокого вложения, если вы не добавите больше & vbTab &s.


Кроме того, вместо использования текущего выделения (т. Е. Необходимо поместить курсор в документ), попытайтесь поместить текст в теле относительно определенной строки текста (static void Main(string[] args) в этом случае)?

Вы отметили в своем ответе, что эта конкретная строка не всегда нужна, но вместо нее используется расположение курсора. Я просто пытался указать, что это был вариант. Если вы измените searchText в приведенном ниже коде вы можете поместить вставленный текст практически в любом месте. Это также можно изменить для поиска текста у курсора.

Что-то вроде этого (непроверенного) кода:

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)

я полагаю, что vsEPReplaceTextOptions.vsEPReplaceTextAutoformat (не подтверждено) также автоматически введет для вас ваш код.

( Смотрите здесь для получения дополнительной информации / идей)

Другие вопросы по тегам