Did you ever want to write very long string constant in your source code? You surely did if you wanted to display longer text in message box, for example. Or you wanted to create a macro which generates some longer source code. In this case you needed the code template stored in a string if you didn't want to read it from a file.
Then you know it is not the easiest thing. You cannot simply paste the text into source code. What if the string text contains 1000 words and newlines? I will discuss a macro which generates VB version of long string here. But hey, non-VB people, don't go away! You already know that VB is a language of VS macros so it can be useful to you too. And you can easily modify the macro to produce string in other languages.
Let's say we want a string with the following text:
This is long
text with
several lines and
"some words in quotes".
The VB code for such string could look like:
Dim str as String = "This is long" + vbCrLf + "text with" + _
"several lines and" + vbCrLf + """some words in quotes""."
As you can see, we cannot simply paste original text to the code. We need to replace newlines with vbCrLf and escape " with "". This could be enough but we also don't want very long lines. So we split the line with standard VB line continuation sequence ' _'. That's all. Those of us who don't have free few hours to do it manually will use the following macro.
The macro takes text from clipboard, performs the string manipulation and pastes the result to the current cursor position.
Create pasteLongTextToCode macro:
Dim cliptext As String
'''<summary>Pastes the text from clipboard as the string definition in source
'''code.</summary>
'''<remarks>The text is enclosed within double quotes. Double quotes in the text
'''are escaped by "". New lines are escaped as well. If the text is too
'''long, the expression is splitted to multiple lines using "+
'''_".</remarks>
Sub pasteLongTextToCode()
Dim lineLimit As Integer = 80
Dim text As String
Dim ClipBoardThread As System.Threading.Thread = New System.Threading.Thread(AddressOf getStringFromClipboard)
With ClipBoardThread
.ApartmentState = System.Threading.ApartmentState.STA
.IsBackground = True
.Start()
'-- Wait
.Join()
End With
ClipBoardThread = Nothing
text = cliptext
Dim newText As String
Dim line As String
Dim lines As New Collection()
' escape "
newText = text.Replace("""", """""")
' crlf -> cr, not to be splitted in the next step
newText = newText.Replace(vbCrLf, vbCr)
' wrap text to collection of lines
While newText.Length> 0
If newText.Length <= lineLimit Then
line = newText
newText = ""
Else
line = newText.Substring(0, lineLimit)
newText = newText.Remove(0, 80)
End If
lines.Add(line)
End While
' escape newlines and build final text
newText = ""
Dim i As Integer
For i = 1 To lines.Count
line = lines.Item(i)
newText += """" + line.Replace(vbCr, """ + vbCrLf + """) + """"
If i <lines.Count Then
newText += " + _" + vbCrLf
End If
Next
' paste the result
DTE.UndoContext.Open("PasteTextAsString")
Dim txt As TextSelection
txt = DTE.ActiveDocument.Selection
txt.Insert(newText, _
vsInsertFlags.vsInsertFlagsInsertAtEnd)
txt.SmartFormat()
DTE.UndoContext.Close()
End Sub
Sub getStringFromClipboard()
Dim dataObject As System.Windows.Forms.IDataObject = System.Windows.Forms.Clipboard.GetDataObject()
cliptext = (CType(dataObject.GetData(System.Windows.Forms.DataFormats.Text), String))
End Sub
Now you can copy some long text to clipboard and run our macro to paste it. You can of course create a toolbar or menu button or assign keyboard shortcut to it.
You can learn three important things from this macro:
- How to insert the text into current document.
- How to retrieve the data from clipboard. You cannot do this directly. You must create a separate thread for this operation in macro.
- How to handle Undo.