在软件开发过程中,为了提高代码的可读性和维护性,经常需要将代码逻辑上分组。在ComponentScience,非常推崇使用区域(regions)来实现这一点。经过几年的手动操作,决定编写一个宏来简化这个过程。在进行了一些研究之后,找到了一些如何操作Visual Studio代码编辑器的示例。最终,创建了以下宏,用于将代码区域化。
还包含了如何将这个宏安装到Visual Studio中,以及如何将其分配给快捷键的说明。使用Alt+R作为快捷键,因为在Visual Studio文本编辑器中它没有被使用,而且对来说很有意义。
可以随意使用这个宏,甚至可以将其分享给朋友,或者声称是自己编写的。
注意:只在C#文件中使用这个宏。如果想在VB中使用它,那么需要取消注释VB部分,并注释掉C#部分。如果有人知道如何修改脚本来检测正在使用的语言,请告诉,会相应地修改脚本。相信有一种简单的方法,只是还没有研究,因为不在乎。不过,VB部分在VB代码中确实有效。已经测试过了。
更新:在CodeProject上发布这篇文章后,收到了一些读者的反馈,他们提供了如何检测使用的语言、改进填充以及处理制表符和空格的建议。已经根据这些反馈更新了宏。
更多更新!CodeProject上的用户对宏进行了很好的调整!现在有一个非常好的区域化宏。对从CodeProject社区收到的反馈感到非常满意。特别感谢(不分先后顺序)RussKie, simonech, Hrusikesh, ERobishaw, isler-j, 和 SvenRieke。这些人体现了合作开发的精神。
以下是宏代码的示例。请注意,这里只展示了VB版本的代码。
Sub MakeRegion()
Regions.MakeRegion()
End Sub
Public Class Regions
'MakeRegion inserts #region and #endregion tags
'
Shared Sub MakeRegion()
Dim rName As String = ""
Dim pad As String = ""
Dim junk As String
Dim count, i As Integer
Dim startpoint, endpoint, tmppoint As EditPoint
With DTE.ActiveDocument.Selection
startpoint = .TopPoint.CreateEditPoint()
endpoint = .BottomPoint.CreateEditPoint
End With
If startpoint.EqualTo(endpoint) Then
Exit Sub
End If
'ELR: ADDED THIS, to move the startpoint to the start of the line
'so that the Pad function works correctly
If Not startpoint.AtStartOfLine Then
startpoint.StartOfLine()
End If
'IV 2004-12-13: rName = InputBox("Region Name:")
rName = InputBox("Region Name:", "Pick a name", GetDesc(DTE.ActiveDocument.Selection.TopPoint.CreateEditPoint()))
DTE.UndoContext.Open("Insert A Region")
Try
junk = startpoint.GetText(startpoint.LineLength)
pad = String.Empty
For count = 0 To junk.Length - 1
If junk.Substring(count, 1).Equals(vbCrLf) Or junk.Substring(count, 1).Equals(vbTab) Then
pad += junk.Substring(count, 1)
Else
Exit For
End If
Next
'ELR: ADDED Test for Languages
If DTE.ActiveDocument.Language = "CSharp" Then
'C Sharp Code
startpoint.Insert(String.Format("{0}#region {1}{2}", pad, rName, vbCrLf))
If endpoint.LineLength = 0 Then
endpoint.Insert(String.Format("{0}#endregion // {1}{2}", pad, rName, vbCrLf))
Else
endpoint.Insert(String.Format("{0}#endregion // {1}{2}", vbCrLf & pad, rName, vbCrLf))
End If
Else
'VB Code
startpoint.Insert(String.Format("{0}#Region ""{1}""{2}", pad, rName, vbCrLf))
If endpoint.LineLength = 0 Then
endpoint.Insert(String.Format("{0}#End Region '{1}{2}", pad, rName, vbCrLf))
Else
endpoint.Insert(String.Format("{0}#End Region ' {1}{2}", vbCrLf & pad, rName, vbCrLf))
End If
End If
Finally
DTE.UndoContext.Close()
End Try
End Sub
'IV: Get the description from the 1st line of code in the region
'i.e. ignore c# comment tags (///) or take 1st line of the comments (//)
'Requires adjustments for VB and other langs
Private Shared Function GetDesc(ByVal startpoint As EditPoint) As String
Dim line As String = ""
Dim tmppoint As EditPoint
line = startpoint.GetText(startpoint.LineLength)
If (line.Length > 0) Then
line = line.TrimStart(vbCrLf, vbTab)
If DTE.ActiveDocument.Language = "CSharp" Then
If (line.StartsWith("///")) Then
tmppoint = startpoint
tmppoint.LineDown()
line = GetDesc(tmppoint)
ElseIf (line.StartsWith("//")) Then
line = line.TrimStart("//", vbCrLf)
End If
End If
line = line.Replace("{", String.Empty)
End If
line = line.TrimEnd(vbCrLf, vbTab)
Return line
End Function
End Class
要安装这个宏,请打开Visual Studio并按照以下步骤操作:
要将新的MakeRegion宏分配给Alt+R,请按照以下步骤操作: