原文地址:
http://blog.youkuaiyun.com/leatinfy/archive/2010/03/14/5379095.aspx
我们使用VS2005中的宏来编写代码注释插件,其宏代码如下:
- Imports System
- Imports EnvDTE
- Imports EnvDTE80
- Imports System.Diagnostics
- 'Code Comment v1.0
- 'leatinfy <leatinfy@gmail.com>
- Public Module CodeComment
- 'C-M C-H(head of file)
- Sub AddFileHeaderComment()
- If DTE.ActiveDocument.Type = "Text" Then
- Dim selection As EnvDTE.TextSelection
- Dim commText As String
- Dim outTextDoc As TextDocument
- Dim outText As EditPoint
- selection = DTE.ActiveDocument.Selection
- commText = "" + vbCrLf
- outTextDoc = DTE.ActiveDocument.Object ( "TextDocument" )
- outText = outTextDoc.StartPoint.CreateEditPoint()
- outText.MoveToPoint(selection.TopPoint)
- selection.Text = ""
- outText.Insert(commText)
- End If
- End Sub
- '
- 'C-M C-C(code comment)
- Sub AddCommentStyle1()
- If DTE.ActiveDocument.Type = "Text" Then
- Dim selection As EnvDTE.TextSelection
- Dim commText As String
- Dim topline As Integer
- selection = DTE.ActiveDocument.Selection
- topline = selection.TopLine
- commText = ""
- selection.Text = commText
- selection.MoveToLineAndOffset(topline + 1, 1)
- selection.EndOfLine()
- End If
- End Sub
- '
- 'C-M C-A(above the code line)
- Sub AddCommentStyle2()
- If DTE.ActiveDocument.Type = "Text" Then
- Dim selection As EnvDTE.TextSelection
- Dim commText As String
- selection = DTE.ActiveDocument.Selection
- commText = ""
- selection.Text = commText
- selection.CharLeft(, 3)
- End If
- End Sub
- '
- 'C-M C-E (end of the code line)
- Sub AddCommentStyle3()
- If DTE.ActiveDocument.Type = "Text" Then
- Dim selection As EnvDTE.TextSelection
- Dim commText As String
- selection = DTE.ActiveDocument.Selection
- commText = ""
- selection.Text = commText
- selection.CharLeft(, 3)
- End If
- End Sub
- '
- 'C-M C-N(normal c style)
- Sub AddCommentStyle4()
- If DTE.ActiveDocument.Type = "Text" Then
- Dim selection As EnvDTE.TextSelection
- Dim commText As String
- selection = DTE.ActiveDocument.Selection
- commText = ""
- selection.Text = commText
- selection.CharLeft(, 3)
- End If
- End Sub
- 'C-M C-F(function comment)
- Sub AddFunctionComment()
- Dim selection As EnvDTE.TextSelection
- If DTE.ActiveDocument.Type = "Text" Then
- selection = DTE.ActiveDocument.Selection
- Dim functext As String
- Dim funinfo As FuncInfo
- Dim editpoint As EditPoint
- Dim startLine As Integer
- Dim endLine As Integer
- Dim strTmp As String
- Dim commentText As String
- Dim col As Integer
- Dim codefunc As CodeFunction
- codefunc = CType (selection.TopPoint.CodeElement(vsCMElement.vsCMElementFunction), CodeFunction)
- If codefunc Is Nothing Then
- Exit Sub
- End If
- functext = String .Copy(selection.Text)
- commentText = ""
- col = selection.TopPoint.DisplayColumn
- selection.GotoLine(selection.TopLine)
- selection.NewLine()
- selection.LineUp(, 1)
- If col > 1 Then
- selection.PadToColumn(col)
- Else
- selection.Text = GetFirstSpaceText(functext)
- End If
- selection.Text = commentText
- End If
- End Sub
- Public Class FuncInfo
- Public FuncName As String
- Public Args As New Collections.ArrayList
- Public hasReturn As Boolean
- End Class
- Public Structure BracketCount
- Public LCount As Integer
- Public RCount As Integer
- End Structure
- Private Function GetFuncInfo( ByVal funcstxt As String ) As FuncInfo
- Dim index As Integer
- Dim funinfo As New FuncInfo
- Dim strTmp As String
- Dim args As String ()
- index = funcstxt.IndexOf("(" )
- strTmp = funcstxt.Substring(0, index)
- funinfo.FuncName = GetVarPartFromEnd(GetLastWord(strTmp))
- funinfo.hasReturn = HasReturnValue(strTmp)
- If index < 0 Then
- Return funinfo
- End If
- strTmp = funcstxt.Substring(index + 1)
- index = strTmp.IndexOf(")" )
- If index < 0 Then
- Return funinfo
- End If
- strTmp = strTmp.Substring(0, index)
- args = strTmp.Split("," .ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
- Dim i As Integer = 0
- Dim counter As BracketCount
- Dim tmpcounter As BracketCount
- While i < args.Length
- counter.LCount = 0
- counter.RCount = 0
- While i < args.Length
- tmpcounter = GetBracketCount(args(i))
- counter.LCount = counter.LCount + tmpcounter.LCount
- counter.RCount = counter.RCount + tmpcounter.RCount
- If counter.LCount = counter.RCount Then
- Exit While
- Else
- i = i + 1
- End If
- End While
- If i < args.Length And counter.LCount = counter.RCount Then
- funinfo.Args.Add(GetLastWord(args(i)))
- End If
- i = i + 1
- End While
- Return funinfo
- End Function
- Private Function GetVarPartFromEnd( ByVal funcStr As String ) As String
- Dim strLen As Integer
- Dim ch As Char
- strLen = funcStr.Length
- For i As Integer = strLen - 1 To 0 Step -1
- ch = funcStr.Chars(i)
- If (Asc(ch) >= 48 And Asc(ch) <= 57) Or (Asc(ch) >= 65 And Asc(ch) <= 90) Or (Asc(ch) >= 97 And Asc(ch) <= 122) Or ch = "_" c Then
- Continue For
- Else
- Return funcStr.Substring(i + 1)
- End If
- Next
- Return funcStr
- End Function
- Private Function GetLastWord( ByVal str As String ) As String
- Dim strLen As Integer
- Dim index As Integer
- Dim strTmp As String
- str = str.TrimEnd((" " + vbTab + vbLf + vbCrLf).ToCharArray())
- strLen = str.Length
- For i As Integer = strLen - 1 To 0 Step -1
- If str.Chars(i) = " " Or str.Chars(i) = vbTab Or str.Chars(i) = vbLf Or str.Chars(i) = vbCrLf Then
- Return str.Substring(i + 1)
- End If
- Next
- Return str
- End Function
- Private Function GetBracketCount( ByVal str As String ) As BracketCount
- Dim strLen As Integer
- Dim counter As BracketCount
- counter.LCount = 0
- counter.RCount = 0
- strLen = str.Length
- For i As Integer = 0 To strLen - 1
- If str.Chars(i) = "<" c Then
- counter.LCount = counter.LCount + 1
- End If
- If str.Chars(i) = ">" c Then
- counter.RCount = counter.RCount + 1
- End If
- Next
- Return counter
- End Function
- Private Function GetFirstTextPosition( ByVal str As String , ByVal tabSize As Integer ) As Integer
- Dim strLen As Integer
- Dim pos As Integer = 0
- strLen = str.Length
- Dim i As Integer = 0
- For i = 0 To strLen - 1
- If str.Chars(i) = " " c Then
- pos = pos + 1
- ElseIf str.Chars(i) = vbTab Then
- pos = pos + tabSize
- Else
- Return pos
- End If
- Next i
- Return pos
- End Function
- Private Function GetFirstSpaceText( ByVal str As String ) As String
- Dim strLen As Integer
- Dim pos As Integer = 0
- strLen = str.Length
- Dim i As Integer = 0
- For i = 0 To strLen - 1
- If str.Chars(i) <> " " And str.Chars(i) <> vbTab Then
- Exit For
- End If
- Next i
- Return str.Substring(0, i)
- End Function
- 'check function has return value
- Private Function HasReturnValue( ByVal str As String ) As Boolean
- Dim strs As String ()
- strs = str.Split((" " + vbTab + vbLf + vbCrLf).ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
- Return Not Array.Exists(strs, AddressOf IsVoidKeyWords)
- End Function
- Private Function IsVoidKeyWords( ByVal str As String ) As Boolean
- If str.ToLower() = "void" Then
- Return True
- Else
- Return False
- End If
- End Function
-
End
Module
接下来我们简单说一下如何使用这个注释插件。在“工具->宏->宏IDE”先启动宏IDE,然后新建一个宏项目,就上面的宏代码copy进 去,接着就在VS2005中绑定快捷键,在“工具->选项->键盘”中选定相应的宏函数,然后分配快捷键。宏中的函数前面注释中的快捷键为推 荐的快捷键,自己完全可以跟根自身的喜好来设定。
比如,我们选中函数getname,然后按C-M C-F(我绑定的是这两个键),然后生成函数上面部分的代码
- int getname( int id)
- {
- ...
- }
注:GetFuncInfo GetVarPartFromEnd GetLastWord GetBracketCount HasReturnValue IsVoidKeyWords这几个函数为我自已通过分析字符串来分析函数的参数代码,在查阅文档时发现可以通过.Net的 CodeElement(vsCMElement.vsCMElementFunction)过获取函数的相应信息,就对生成函数注释的宏代码进行了修 改,这几个函数仅供大家参考,在AddFunctionComment中并没有调用。