在上篇中,我给了一个格式化Java代码的IDE宏的示例。
该宏的代码存在不少错误,而且还有效率上的问题。用正则重写了一遍。当然,由于个人能力有限,而且未加测试,错误在所难免,欢迎指出,将不断完善,下面是完整的代码:
Imports System
Imports System.Collections.Generic
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics
Public Module TieWen
Sub DTEReplaceAll(ByVal Target As EnvDTE.vsFindTarget, ByVal From As String, ByVal sTo As String, Optional ByVal FindPattern As vsFindPatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxLiteral, Optional ByVal bLoop As Boolean = False)
DTE.Find.FindWhat = From
DTE.Find.ReplaceWith = sTo
DTE.Find.Target = Target
DTE.Find.MatchCase = True
DTE.Find.MatchWholeWord = False
DTE.Find.MatchInHiddenText = False
DTE.Find.PatternSyntax = FindPattern
DTE.Find.ResultsLocation = vsFindResultsLocation.vsFindResultsNone
DTE.Find.Action = vsFindAction.vsFindActionReplaceAll
While ((DTE.Find.Execute() <> vsFindResult.vsFindResultNotFound) And bLoop)
End While
End Sub
' 以上几个是辅助Sub,而不是宏
Sub Macro_FormatJava()
'在VS2010查找对话框中使用的正则:
'<匹配字首,>匹配字尾
'用{}来保存匹配值(在js中是())
':有特殊的用途;:i:C++标识符(变量名、类名等),:q:双引号括起来的字符串(该匹配似乎有问题)
'完整的正则参考:http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=ZH-CN&k=k(VS.REGULAREXPRESSIONBUILDER)&rd=true
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\{", " {", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '去除{前无用的空格换行等(如果换行是特意增加的,则会丢失)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "\{:b*{[^\n]}", "{" + vbCrLf + "\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '如果{后没有换行,则增加换行
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[^:b\n]}:b*\}", "\1" + vbCrLf + "}", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '如果}前没有换行,则增加
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "\}:b*{[^\n]}", "}" + vbCrLf + "\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '如果}后没有换行,则增加
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, ";:b*{[^\n]}", ";" + vbCrLf + "\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '如果;后没有换行,则增加换行
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*{[\+-\*/%&\|\^=\?\:<>]}[:b\n]*", " \1 ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '+-*/%&|^=?:<>前后增加空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[\+-\*/%&\|\^=\<\>!]}[:b\n]+=[:b\n]*", "\1= ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '+=,-=,*=,/=,%=,&=,|=,^=,==,<=,>=,!=,==前后增加空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "&[:b\n]+&", "&&", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '&&
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "\|[:b\n]+\|", "||", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '||
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\,[:b\n]*", ", ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) ',后加空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "\:[:b\n]*\:[:b\n]*\:[:b\n]*", ": ::", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) 'case xxx: ::或 a ? b : ::GetInt()
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[^\::a_]}[:b\n]*\:[:b\n]*\:[:b\n]*", "\1 ::", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) 'x += ::GetInt()
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[:a_]}[:b\n]*\:[:b\n]*\:[:b\n]*", "\1::", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) 'x::GetInt()
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[:a_]}[:b\n]*-[:b\n]*>[:b\n]*", "\1->", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) 'x->GetInt()
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[:a_]}[:b\n]*\.[:b\n]*", "\1.", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) 'x.GetInt() 或小数
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{^:i}[:b\n]*{[&\*]}[:b\n]*{:i}", "\1 \2\3", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '一元用于变量:&*,前加空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{^:i}[:b\n]*{[\~!\+-]}[:b\n]*{[:a_]}", "\1 \2\3", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '一元用于变量或常量:~!+-,前加空格
'后缀++、--
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{:i}[:b\n]*\+[:b\n]*\+[:b\n]*", "\1++ ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{:i}[:b\n]*-[:b\n]*-[:b\n]*", "\1-- ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'前缀++、--
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\+[:b\n]*\+[:b\n]*{:i}", " ++\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*-[:b\n]*-[:b\n]*{:i}", " --\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\<[:b\n]*\<[:b\n]*=[:b\n]*", " <<= ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '<<=前后加空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\>[:b\n]*\>[:b\n]*=[:b\n]*", " >>= ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr) '>>=前后加空格
'< <,> >:指在C++模板中
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "\<[:b\n]{2,}\<", "< <", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "\>[:b\n]{2,}\>", "> >", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'<<,>>:二元操作符左移右移,前后加空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\<\<[:b\n]*", " << ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\>\>[:b\n]*", " >> ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'//,/*,*/,**
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*/[:b\n]*/[:b\n]*", " // ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*/[:b\n]*\*[:b\n]*", "/*", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\*[:b\n]*/[:b\n]*", "*/", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*\*[:b\n]**\[:b\n]*", "**", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'/*,*/前若无换行则增加
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[^:b\n]}:b*{/\*+}", "\1" + vbCrLf + "\2", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[^:b\n]}:b*{\*+/}", "\1" + vbCrLf + "\2", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'/*,*/后若无换行则增加
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{/\*+}:b*{[^\n]}", "\1" + vbCrLf + "\2", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{\*+/}:b*{[^\n]}", "\1" + vbCrLf + "\2", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'去除;前的空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]*;", ";", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'()[]去除空格,处理内部的空格即可,外部和符号相关的已在上面处理完毕
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[\(\[]}[:b\n]+", "\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b\n]+{[\)\]]}", "\1", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'去除多余的空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "[:b]+", " ", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
'调用ALT+F8格式化选中区
DTE.ActiveDocument.Selection.SelectAll()
DTE.ExecuteCommand("Edit.FormatSelection")
'将Tab替换成四个空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, vbTab, " ", vsFindPatternSyntax.vsFindPatternSyntaxLiteral)
'去除行尾的空格
DTEReplaceAll(vsFindTarget.vsFindTargetCurrentDocument, "{[^:b\n]}:b*{[\n]}", "\1\2", vsFindPatternSyntax.vsFindPatternSyntaxRegExpr)
End Sub
End Module