总所周知,在Windows开发环境中,一个几百兆C语言工程代码中,最好用的编辑工具当然就是Source Insight了。Source Insight(目前大多使用的版本为3.5)的Macro Language提供的API非常强大,其实我们可以利用这些API编写一些脚本,通过映射快捷键来达到高效而规范开发的目的。
而在一个团队协作开发的项目中,如果后期主要工作是Debug,那么仅仅只是规范注释,对于问题的追踪,代码的美观都显得尤为重要。因为Source Insight可以自定义出各种功能的脚本。本文只介绍如何利用Source Insight的宏语言编写脚本,快速添加统一规范化的注释。
打开Source Insight,按F1,会出来Source Insight Help文档,里面有个Macro Language Guide,相信大家看完之后,都可以尝试着去编写各种各样的脚本出来。正如Vim出来之后,很多牛人编写了功能强大的插件一样,让Vim成为Linux下的一件编辑利器。本人也是通过尝试,花了一个晚上时间写出来一个添加注释的简单脚本。在此贴出我的脚本,文件名为 BryanCommentsV1.0.em:
/*
*************************************************************
* Comments Add File
* Copy Rights by BryanZhu @2010-2046
*
* FileName: BryanCommentsV1.0.em
* Author: BryanZhu
* Email: [email protected]
* Date: 2010-08-29
*
*************************************************************
*/
/*
*************************************************************
* FunctionName : GetStandardTimeString
* Description : get the system time by YYYY/MM/DD format.
* ReturnValue : return a system time string.
* Parameter[0] :
* Parameter[1] :
* Author : BryanZhu
* Date : 2010-08-29
*************************************************************
*/
macro GetStandardTimeString()
{
var szSysTime
var szYear
var szMonth
var szDay
var szTempMonth
var szTempDay
var szTimeString
szSysTime = GetSysTime(1)
szYear = szSysTime.Year
szTempMonth = szSysTime.Month
szTempDay = szSysTime.Day
if(szTempMonth < 10)
{
szMonth = "0@szTempMonth@"
}
else
{
szMonth = szTempMonth
}
if(szTempDay < 10)
{
szDay = "0@szTempDay@"
}
else
{
szDay = szTempDay
}
szTimeString = "@szYear@/@szMonth@/@szDay@"
return szTimeString
}
/*
*************************************************************
* FunctionName : InsertCommentsInfo
* Description : Save Basic Comments Info in a special file to parse the info.
* by other macro functions.
* ReturnValue : NONE
* Parameter[0] :
* Parameter[1] :
* Author : BryanZhu
* Date : 2010-08-29
*************************************************************
*/
macro InsertCommentsInfo(hbuf)
{
var szModifyID
var szAuthorName
var szComment
szModifyID = "ModifyID:RF00000000"
szAuthorName = "AuthorName:BryanZhu"
szComment = "Comment:Please_input_your_comment_statement_here."
InsBufLine(hbuf, 0, szModifyID)
InsBufLine(hbuf, 1, szAuthorName)
InsBufLine(hbuf, 2, szComment)
}
/*
*************************************************************
* FunctionName : BryanSaveCommentsInfo
* Description : save the infomation of comments
* ReturnValue : NONE
* Parameter[0] :
* Parameter[1] :
* Author : BryanZhu
* Date : 2010-08-29
*************************************************************
*/
macro BryanSaveCommentsInfo()
{
var filename
var NewFileBufName
var hbuf
var hwnd
var hprj
var nProjFileCount
var iFileIndex
var tempFileName
filename = "CommentsConfigFile.bryan"
//judge the comments info file if is in current project.
hprj = GetCurrentProj()
nProjFileCount = GetProjFileCount(hprj)
iFileIndex = 0
while(iFileIndex < nProjFileCount)
{
tempFileName = GetProjFileName(hprj, iFileIndex)
if(tempFileName == filename)
{
//Msg("@filename@ file is existed in this project...")
hbuf = OpenBuf(filename)
if(hbuf != hNil)
{
hwnd = NewWnd(hbuf)
if(hwnd != hNil)
{
SaveBufAs(hbuf, filename)
AddFileToProj(hprj, filename)
}
else
{
Msg("Create new window error!-1")
}
}
else
{
Msg("Create new empty file buffer error!-1")
}
break
}
else
{
iFileIndex = iFileIndex + 1
if(iFileIndex == nProjFileCount)
{
//Msg("@filename@ file is not existed in this project...")
hbuf = NewBuf(NewFileBufName)
if(hbuf != hNil)
{
hwnd = NewWnd(hbuf)
if(hwnd != hNil)
{
hprj = GetCurrentProj()
InsertCommentsInfo(hbuf)
SaveBufAs(hbuf, filename)
AddFileToProj(hprj, filename)
}
else
{
Msg("Create new window error!-2")
}
//CloseBuf(hbuf)
}
else
{
Msg("Create new empty file buffer error!-2")
}
break
}
}
}
stop
}
macro GetCommentsInfoFileName()
{
return "CommentsConfigFile.bryan"
}
macro IsCommentsInfoFileExist()
{
var filename
var hprj
var nProjFileCount
var iFileIndex
var tempFileName
filename = "CommentsConfigFile.bryan"
hprj = GetCurrentProj()
nProjFileCount = GetProjFileCount(hprj)
iFileIndex = 0
while(iFileIndex < nProjFileCount)
{
tempFileName = GetProjFileName(hprj, iFileIndex)
if(tempFileName == filename)
{
return 1 // File is exist.
}
else
{
iFileIndex = iFileIndex + 1
}
}
return 0 // File is not exist.
}
macro GetCommentsInfo(iBufLineIndex)
{
var filename
var hbuf
var szText
var nBufLineCount
var nTextLength
filename = GetCommentsInfoFileName()
if(IsCommentsInfoFileExist())
{
hbuf = OpenBuf(filename)
if(hbuf != hNil)
{
nBufLineCount = GetBufLineCount(hbuf)
if(iBufLineIndex <= nBufLineCount)
{
szText = GetBufLine(hbuf, iBufLineIndex)
nTextLength = strlen(szText)
if(iBufLineIndex == 0)
{
szText = strmid(szText, 9, nTextLength)
}
else if(iBufLineIndex == 1)
{
szText = strmid(szText, 11, nTextLength)
}
else if(iBufLineIndex == 2)
{
szText = strmid(szText, 8, nTextLength)
}
CloseBuf(hbuf)
return szText
}
else
{
Msg("GetCommentsInfo() parameter @iInfoIndex@ error....")
}
}
else
{
Msg("GetModifyIDofCommentsInfo(): Open buffer fail...")
stop
}
}
else
{
Msg("@filename@ is not exist...")
stop
}
}
/*
*************************************************************
* FunctionName : BryanAddSelBlockComments
* Description : add comments to contain the selected block statements.
* ReturnValue : NONE
* Parameter[0] :
* Parameter[1] :
* Author : BryanZhu
* Date : 2010-08-29
*************************************************************
*/
macro BryanAddSelBlockComments()
{
var hwnd
var hbuf
var firstSelLine
var lastSelLine
var sztempFirstRemark
var sztempLastRemark
var szFirstRemark
var szLastRemark
var szfirstSelLineText
var szTimeString
var szModifyID
var szAuthorName
var szComment
var ichIndex
sztempFirstRemark = "// <-"
sztempLastRemark = "// ->"
szFirstRemark = Nil
szLastRemark = Nil
szTimeString = GetStandardTimeString()
szModifyID = GetCommentsInfo(0)
szAuthorName = GetCommentsInfo(1)
szComment = GetCommentsInfo(2)
if(IsCommentsInfoFileExist())
{
sztempFirstRemark = sztempFirstRemark # szModifyID # "-" # szAuthorName # "-" # szTimeString # "-" # szComment
sztempLastRemark = sztempLastRemark # szModifyID # "-" # szAuthorName
hwnd = GetCurrentWnd()
hbuf = GetCurrentBuf()
firstSelLine = GetWndSelLnFirst(hwnd)
lastSelLine = GetWndSelLnLast(hwnd)
szfirstSelLineText = GetBufLine(hbuf, firstSelLine)
ichIndex = 0
while(szfirstSelLineText[ichIndex] == "" || szfirstSelLineText[ichIndex] == "\t")
{
if(szfirstSelLineText[ichIndex] == "" )
{
szFirstRemark = cat(szFirstRemark, "")
szLastRemark = cat(szLastRemark, "")
}
else
{
szFirstRemark = cat(szFirstRemark, "\t")
szLastRemark = cat(szLastRemark, "\t")
}
ichIndex = ichIndex + 1
}
szFirstRemark = cat(szFirstRemark, sztempFirstRemark)
szLastRemark = cat(szLastRemark, sztempLastRemark)
InsBufLine(hbuf, firstSelLine, szFirstRemark)
InsBufLine(hbuf, lastSelLine+2, szLastRemark)
SaveBuf(hbuf)
}
else
{
BryanSaveCommentsInfo()
}
stop
}
将BryanCommentsV1.0.em拷贝到Source Insight的Base项目所在的文件夹下,比如 C:\Documents and Settings\Source Insight\Projects\Base ,然后打开Source Insight的Base项目,通过菜单Project -> Add and Remove Project Files... ,将BryanCommentsV1.0.em添加进Base项目。
打开Menu -> Menu Assignments, Menu栏选择Work菜单(当然,你想把自定义的Macro功能添加到哪个菜单都行。笔者以Work菜单为例) ,在Command栏输入macro快速查找,这时会出现Macro: BryanAddSelBlockComments和Macro: BryanSaveCommentsInfo两个在脚本里自定义的宏,选中Menu Contents里的
在Work菜单中,点击BryanSaveCommentsInfo,这时可以编辑ModifyID,这个ID可以是你的BUG库ID,可以编辑AuthorName为自己的姓名,可以编辑Comment注释信息,编辑之后保存即可。在点击BryanSaveCommentsInfo的那一刻,脚本生成了一份CommentsConfigFile.bryan注释配置文件并添加进你所在的工程,这个文件保存着你的注释配置信息。如图1所示。
图1
这时可以在代码中选中某个模块,或者函数,或者语句块,如图2所示,点击BryanAddSelBlockComments,则注释就添加进去了,如图3所示。在注释中,可以通过搜索BUG ID,直接追踪你修改的所有代码,也可以通过姓名搜索追踪你修改的所有功能。不仅方便查询,而且注释格式风格一样,一目了然,便于阅读,利于代码规范。
图2
图3
大家有兴趣,可以自定义各种各样有利于代码规范和提供工作效率的脚本。关于Source Insight和VC6.0,Visual Studio2008关联的用法,以后再做介绍。
半童
2011.10.15北京
Email: [email protected]