Reformat C/C++ code
So you finally got your hands on this awesome piece of C/C++ code that promises to solve your burning problem! You download it and open it inside DevStudio to see how it works and guess what? It looks like crap! I mean, the person who wrote the code used the Martian convention to write it. Granted, it may work, but the way it looks makes it hard to see how.
So you press a button on your toolbar which runs a macro and presto! Everything becomes instantly formatted just the way you like it!
That's what my MakeCodeNicer macro does (below). I got tired of grunting and fixing other people's code with the Find/Replace box so I wrote a nifty little macro that rearranges things such as parenthesis, braces, and brackets to make everything look more civilized.
My coding style happens to look a lot like Microsoft's. However, I'm aware that not everyone likes it (as much as I wish they did) so please feel free to change things to suit your own tastes. Each Find/Change iteration has a comment preceding it which explains what it does.
Enjoy!
Option Explicit
'----------------------------------------------------------
'FILE DESCRIPTION: Routines to reformat C/C++ code.
'----------------------------------------------------------
Sub MakeCodeNicer()
'DESCRIPTION: Reformats the source code to look nicer, the
' way I like it.
'Written by Alvaro Mendez on 06/10/1999
' Taken from
' http://codeguru.developer.com/devstudio_macros/MakeCodeNicer.shtml
' Check that the current document can be changed
if ActiveDocument.ReadOnly then
' If we're connected to SourceSafe, let it prompt for
' check out
ActiveDocument.Selection = "a"
ActiveDocument.Undo
if ActiveDocument.ReadOnly then ' check again
MsgBox "This macro cannot be executed on a read-only file",_
vbExclamation
exit sub
end if
end if
' Save current line so we can return to it at the end
dim nLine
nLine = ActiveDocument.Selection.CurrentLine
' Add spaces in a few places and get rid of it in others
Replace "\:b+;", ";"
Replace "\:b+::\:b+", "::"
Replace "\:b+(", "("
Replace "if(", "if ("
Replace "for(", "for ("
Replace "while(", "while ("
Replace "switch(", "switch ("
Replace "catch(", "catch ("
Replace "return(", "return ("
Replace "(\:b+", "("
Replace "\:b+)", ")"
Replace ";)", "; )"
Replace ";;\:b+)", ";;)"
Replace "\[\:b+", "["
Replace "\:b+\]", "]"
Replace "\:b+\[", "["
' Make sure these statements don't end on the same line
' they started.
BreakSingleLiners "if ("
BreakSingleLiners "for ("
BreakSingleLiners "switch ("
' Break up any lines containing multiple statements
BreakLinesWithMultipleStatements
' Make sure braces are on lines by themselves (unless
' followed by comments)
IsolateOnLeft "{"
IsolateOnRight "{"
IsolateOnRight "}"
IsolateOnLeft "}"
' Break up case statements appearing on single lines
IsolateOnRight "case .+: "
IsolateOnLeft "break;"
' Add a space between these operators
FixOperator "=", 1
FixOperator "==", 2
FixOperator "!=", 2
FixOperator "\+=", 2
FixOperator "-=", 2
FixOperator "\*=", 2
FixOperator "/=", 2
FixOperator "\+", 1
FixOperator "-", 1
FixOperator "<=", 2
FixOperator ">=", 2
FixOperator "<<", 2
FixOperator ">>", 2
FixOperator "&&", 2
FixOperator "||", 2
FixOperator "|", 1
FixLessThanOperator
FixExponents
' Append a space after these
AppendSpace ","
AppendSpace ";"
' Make sure C++ comments (followed by words) have a space
' after them
while ActiveDocument.Selection.FindText("//[A-Z,a-z,0-9]", _
dsMatchRegExp)
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.CharLeft
ActiveDocument.Selection = " "
wend
' Replace all the trailing whitespace (thanks to
' Paul Bludov)
ActiveDocument.Selection.ReplaceText "\:b+\($\)", "\1", _
dsMatchRegExp
' Fix tabs within code surrounded by braces
TabifyMatchingBraces
' Remove any lines that are considered extraneous (ie.
' extra blank lines)
RemoveExtraneousLines
' Indent every "case" inside switch statements (thanks
' to Jim Cooper)
IndentSwitchBody
' Go back to where we were at the beginning
ActiveDocument.Selection.GoToLine nLine
End Sub
' Is the cursor currently within a quoted string
' (or character)
function IsWithinQuotes
dim nCurrentLine, nCurrentColumn, iPos, strBuffer, nCount
nCurrentLine = ActiveDocument.Selection.CurrentLine
nCurrentColumn = ActiveDocument.Selection.CurrentColumn
ActiveDocument.Selection.Cancel
ActiveDocument.Selection.StartOfLine dsFirstText, dsExtend
nCount = 0
iPos = 0
strBuffer = ActiveDocument.Selection
' Count all occurrences of a double quote which apply
' to quoted strings
do while true
iPos = InStr(iPos + 1, strBuffer, """", vbTextCompare)
if not (iPos > 0) then
exit do
end if
' if it's the first character, then it's valid
if iPos = 1 then
nCount = nCount + 1
else
' Make sure it's not preceded by a \ or a \\
if Mid(strBuffer, iPos - 1, 1) <> "\" then
nCount = nCount + 1
elseif (iPos > 2) _
and (Mid(strBuffer, iPos - 2, 1) = "\") then
nCount = nCount + 1
end if
end if
loop
' If number of quotes is odd, we must be inside
' a quoted string!
IsWithinQuotes = ((nCount > 0) and ((nCount Mod 2) <> 0))
ActiveDocument.Selection.MoveTo nCurrentLine, nCurrentColumn
' If we're not inside a quoted string, check for a
' quoted character
if not IsWithinQuotes then
ActiveDocument.Selection.CharLeft dsExtend
' If we find a quoted character left of us, check
' for one on the right
if ActiveDocument.Selection = "'" then
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.CharRight dsExtend
if ActiveDocument.Selection = "\" then
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.CharRight dsExtend
end if
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.CharRight dsExtend
if ActiveDocument.Selection = "'" then
IsWithinQuotes = true
end if
end if
ActiveDocument.Selection.MoveTo nCurrentLine, nCurrentColumn
end if
' If we're inside quotes, proceed from the next character
if IsWithinQuotes then
ActiveDocument.Selection.CharRight
end if
end function
' Is current selection preceded by a C++ comment? ("//")
function IsWithinComment
dim nCurrentLine, nCurrentColumn
nCurrentLine = ActiveDocument.Selection.CurrentLine
nCurrentColumn = ActiveDocument.Selection.CurrentColumn
ActiveDocument.Selection.Cancel
ActiveDocument.Selection.StartOfLine dsFirstText, dsExtend
IsWithinComment = false
if (InStr(1, ActiveDocument.Selection, "//", vbTextCompare) _
> 0) then
IsWithinComment = true ' since it's commented out
nCurrentLine = nCurrentLine + 1 ' we proceed from the next line
end if
ActiveDocument.Selection.MoveTo nCurrentLine, 1
end function
' Should the current selection be ignored?
' (ie., is it within a comment or between quotes?)
function ShouldIgnore
ShouldIgnore = false
if IsWithinQuotes then
ShouldIgnore = true
exit function
end if
if IsWithinComment then
ShouldIgnore = true
end if
end function
' Put the cursor at the top of the document and return ""
' to be passed initially to GetCurrenPosition
function InitializePosition
ActiveDocument.Selection.StartOfDocument
InitializePosition = ""
end function
' Retrieve the current position and return true if it's
' greater than the last one. This is used to ensure that
' the file is only searched once (provided the search is
' started from the top)
function GetCurrentPosition(strPos)
dim nLastLine, nLastColumn, nCurrentLine
dim nCurrentColumn, iPos, ch
nLastLine = -1
nLastColumn = -1
nCurrentLine = ActiveDocument.Selection.CurrentLine
nCurrentColumn = ActiveDocument.Selection.CurrentColumn
' Parse the last position and extract the line and column
for iPos = 1 to Len(strPos)
ch = Mid(strPos, iPos, 1)
if ch = "," then
nLastLine = Int(Mid(strPos, 1, iPos))
nLastColumn = Int(Mid(strPos, iPos + 1))
exit for
end if
next
' Return true if we're currently past the last position
strPos = nCurrentLine & "," & nCurrentColumn
GetCurrentPosition = (nCurrentLine > nLastLine) or _
((nLastLine = nCurrentLine) and (nCurrentColumn > nLastColumn))
end function
' Move by a certain number of columns
sub MoveByColumns(nBy)
ActiveDocument.Selection.MoveTo _
ActiveDocument.Selection.CurrentLine, _
ActiveDocument.Selection.CurrentColumn + nBy
end sub
' Replace the given strFrom with strTo case sensitively
sub Replace(strFrom, strTo)
dim strLastPos, bContinue
strLastPos = InitializePosition
do while ActiveDocument.Selection.FindText(strFrom, _
dsMatchCase + dsMatchRegExp)
bContinue = GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts
' the cursor at the beginning of the line
ActiveDocument.Selection.FindText strFrom, _
dsMatchCase + dsMatchRegExp
ActiveDocument.Selection = strTo
elseif not bContinue then
exit do
end if
loop
end sub
' Break the given str ending in (, so that instead
' of this:
' if (a) return b;
' it looks like this:
' if (a)
' return b;
sub BreakSingleLiners(str)
dim strLastPos, strFound, nCol, bBreak, strAfterFound
' Verify str ends in (, the beginning parenthesis
if Right(str, 1) <> "(" then
exit sub
end if
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText(str, dsMatchCase) _
and GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText str, dsMatchCase
' Find the matching brace and go to the end of the line
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.CharLeft
ExecuteCommand "GoToMatchBrace"
ActiveDocument.Selection.CharRight
nCol = ActiveDocument.Selection.CurrentColumn
ActiveDocument.Selection.EndOfLine dsExtend
strFound = LTrimTabs(ActiveDocument.Selection)
' If there's anything after the brace that isn't a comment, move
' it to the next line
if (Len(strFound) > 0) and (Left(strFound, 1) <> "/") then
bBreak = false
' Check if there's a "{" after the statement which should
' also be broken into multiple lines
if (Mid(strFound, 1, 1) = "{") and (Len(strFound) > 1) then
strAfterFound = LTrimTabs(Mid(strFound, 2))
if strAfterFound <> "" then
ActiveDocument.Selection = "{" + strAfterFound
ActiveDocument.Selection.MoveTo _
ActiveDocument.Selection.CurrentLine, nCol
ActiveDocument.Selection.NewLine
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.NewLine
bBreak = true ' primitive but it works
end if
end if
if not bBreak then
ActiveDocument.Selection = strFound
ActiveDocument.Selection.MoveTo _
ActiveDocument.Selection.CurrentLine, nCol
ActiveDocument.Selection.NewLine
end if
end if
end if
wend
end sub
' Trim blanks AND tabs from the left side
function LTrimTabs(str)
dim iPos, ch
for iPos = 1 to Len(str)
ch = Mid(str, iPos, 1)
if ch <> " " and ch <> vbTab then
exit for
end if
next
LTrimTabs = Mid(str, iPos)
end function
' Isolate the given str on a new line with nothing left of it
sub IsolateOnLeft(str)
dim strLastPos, nLen, bContinue, nCurrentLine, nCurrentColumn
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText("^.*" & str, dsMatchRegExp) _
and GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "^.*" & str, dsMatchRegExp
' Get the length of the found string
' (which may have been a regular expression)
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.FindText str, _
dsMatchBackward + dsMatchRegExp
nLen = Len(ActiveDocument.Selection)
ActiveDocument.Selection.CharLeft
if not ShouldIgnore then
' Now that we have the length, we need to redo
' the search and go on
ActiveDocument.Selection.StartOfLine
ActiveDocument.Selection.FindText "^.*" & str, dsMatchRegExp
bContinue = false
' If we're isolating a brace, make sure its matching brace
' isn't on the same line
if (str = "{") or (str = "}") then
ActiveDocument.Selection.CharRight
nCurrentLine = ActiveDocument.Selection.CurrentLine
nCurrentColumn = ActiveDocument.Selection.CurrentColumn
ActiveDocument.Selection.CharLeft
ExecuteCommand "GoToMatchBrace"
if ActiveDocument.Selection.CurrentLine = nCurrentLine then
ActiveDocument.Selection.MoveTo _
nCurrentLine, nCurrentColumn
bContinue = true ' we found it so move to the next match
else
ActiveDocument.Selection.MoveTo nCurrentLine, 1
ActiveDocument.Selection.FindText "^.*" & str, _
dsMatchRegExp
end if
end if
if LTrimTabs(ActiveDocument.Selection) <> str and _
not bContinue then
ActiveDocument.Selection.CharRight
MoveByColumns -nLen
ActiveDocument.Selection.NewLine
MoveByColumns nLen
end if
GetCurrentPosition strLastPos
end if
end if
wend
end sub
' Isolate the given str so that everything after it is placed
' on the next line
sub IsolateOnRight(str)
dim strLastPos, strRight, nCurrentLine, nCurrentColumn, nLen
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText(str & ".+$", dsMatchRegExp) and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
ActiveDocument.Selection.CharLeft
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText str & ".+$", dsMatchRegExp
' Get the length of the found string
' (which may have been a regular expression)
ActiveDocument.Selection.CharLeft
ActiveDocument.Selection.FindText str, dsMatchRegExp
nLen = Len(ActiveDocument.Selection)
' Now that we have the length, we need to redo the
' search and go on
ActiveDocument.Selection.CharLeft
ActiveDocument.Selection.FindText str & ".+$", dsMatchRegExp
strRight = LTrimTabs(Mid(ActiveDocument.Selection, nLen + 1))
' Handle braces a bit differently
if (str = "{") or (str = "}") then
' If it's a closing brace, and the code after it contains
' a semicolon, leave it alone (ie. variable definition).
if (str = "}") then
ActiveDocument.Selection.EndOfLine dsExtend
if (InStr(1, ActiveDocument.Selection, ";", vbTextCompare) _
> 0) then
strRight = "" ' we found it so move on to the next match
end if
ActiveDocument.Selection.CharLeft
end if
' If we're isolating a brace make sure the matching brace
' isn't on the same line
if (strRight <> "") then
ActiveDocument.Selection.CharLeft
nCurrentLine = ActiveDocument.Selection.CurrentLine
nCurrentColumn = ActiveDocument.Selection.CurrentColumn
ExecuteCommand "GoToMatchBrace"
if ActiveDocument.Selection.CurrentLine = nCurrentLine then
ActiveDocument.Selection.MoveTo _
nCurrentLine, nCurrentColumn + 1
strRight = "" ' we found it so move on to the next match
else
ActiveDocument.Selection.MoveTo _
nCurrentLine, nCurrentColumn
ActiveDocument.Selection.FindText _
str & ".+$", dsMatchRegExp
end if
end if
end if
if (strRight <> "") and _
(Left(strRight, 1) <> "/") and _
(strRight <> ",") and _
(strRight <> ";") and _
(strRight <> "\") then
ActiveDocument.Selection.CharLeft
MoveByColumns nLen
ActiveDocument.Selection.NewLine
end if
end if
wend
end sub
' Place the given strOperator (of nLen REAL characters)
' between spaces (if needed)
sub FixOperator(strOperator, nLen)
dim strLastPos, strFind
strLastPos = InitializePosition
' Add one space between the operator
while ActiveDocument.Selection.FindText("[A-Z,a-z,0-9,\),_,\]]" & _
strOperator & "[A-Z,a-z,0-9,\(,_,\*,"",',&]", dsMatchRegExp) and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
ActiveDocument.Selection.CharLeft
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "[A-Z,a-z,0-9,\),_,\]]" & _
strOperator & "[A-Z,a-z,0-9,\(,_,\*,"",',&]", dsMatchRegExp
ActiveDocument.Selection.CharLeft
ActiveDocument.Selection.CharRight
ActiveDocument.Selection = " "
MoveByColumns nLen
ActiveDocument.Selection = " "
end if
wend
strLastPos = InitializePosition
' Fix any C++ "operator" member functions which were broken above
while ActiveDocument.Selection.FindText("operator " & strOperator & " ", _
dsMatchRegExp) and GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "operator " & strOperator & " ", _
dsMatchRegExp
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.Backspace
MoveByColumns -nLen
ActiveDocument.Selection.Backspace
end if
wend
end sub
' Fix > operator without altering template<T> code and operator <<
function FixLessThanOperator()
dim strLastPos, strFound, strTemplate
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText("^.*[^ <]<.", dsMatchRegExp) and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the search since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "^.*[^ <]<.", dsMatchRegExp
strFound = ActiveDocument.Selection
' Fix the left side
strFound = Left(strFound, Len(strFound) - 2) & " " & _
Right(strFound, 2)
ActiveDocument.Selection = strFound
' Fix the right side
strTemplate = Right(strFound, 11)
if (Left(strTemplate, 8) <> "template") and _
(Right(strFound, 1) <> " ") and _
(Right(strFound, 1) <> "=") and _
(Right(strFound, 1) <> "<") and _
(Right(strFound, 1) <> ">")then
ActiveDocument.Selection.CharLeft
ActiveDocument.Selection = " "
end if
end if
wend
end function
' Append a space after the given strOperator (if it needs it)
sub AppendSpace(strOperator)
dim strLastPos
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText(strOperator & _
"[A-Z,a-z,0-9,\(,\-,_,\*,"",',&]", dsMatchRegExp) and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
ActiveDocument.Selection.CharLeft
if not ShouldIgnore then
ActiveDocument.Selection.FindText strOperator & _
"[A-Z,a-z,0-9,\(,\-,_,\*,"",',&]", dsMatchRegExp
ActiveDocument.Selection.CharLeft
MoveByColumns Len(strOperator)
ActiveDocument.Selection = " "
end if
wend
end sub
' Fix tabbing within function blocks (surrounded by braces)
function TabifyMatchingBraces()
dim strLastPos, cBeforeBrace
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText("{") and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the action since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "{"
' Go to matching brace and reformat tabs
ExecuteCommand "GoToMatchBraceExtend"
ActiveDocument.Selection.SmartFormat
cBeforeBrace = Mid(ActiveDocument.Selection, _
Len(ActiveDocument.Selection) - 1, 1)
' If SmartFormat indents the block (by mistake), unindent it
if (cBeforeBrace = vbTab or cBeforeBrace = " ") then
ActiveDocument.Selection.Unindent
end if
end if
wend
end function
' Since Microsoft's "SmartFormat" is not smart enough to indent case
' statements inside the switch body, we'll do it here.
' (Thanks to Jim Cooper)
function IndentSwitchBody()
dim nSwitchLine, nFirstLine, nLastLine, strLastPos, iLine
strLastPos = InitializePosition
while ActiveDocument.Selection.FindText("switch", _
dsMatchWord + dsMatchCase) and GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
nSwitchLine = ActiveDocument.Selection.CurrentLine
' Now find the opening brace and make sure it's on the next line
if ActiveDocument.Selection.FindText("{") and _
not ShouldIgnore and _
(ActiveDocument.Selection.CurrentLine = nSwitchLine + 1) then
' Repeat the action since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "{"
' Find next line in file, since earlier code put '{' on
' a line by itself
nFirstLine = ActiveDocument.Selection.CurrentLine + 1
' Go to matching brace and reformat tabs
ExecuteCommand "GoToMatchBrace"
' Find previous line in file, since earlier code put '}' on
' line by itself
nLastLine = ActiveDocument.Selection.CurrentLine
' Move to the line after the opening brace
ActiveDocument.Selection.GoToLine nFirstLine, 1
' Select everything between the braces and indent it
for iLine = nFirstLine to nLastLine - 1
ActiveDocument.Selection.LineDown dsExtend
next
ActiveDocument.Selection.Indent
end if
end if
wend
end function
' Remove any lines that are considered extraneous (usually blank ones).
function RemoveExtraneousLines()
dim strLastPos, nCurrentLine, nCurrentColumn
strLastPos = InitializePosition
' Remove any blank lines that fall below any open braces ("{")
while ActiveDocument.Selection.FindText("{") and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the action since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "{"
nCurrentLine = ActiveDocument.Selection.CurrentLine
nCurrentColumn = ActiveDocument.Selection.CurrentColumn
ActiveDocument.Selection.LineDown
' Cut any blank lines below the {
do while true
ActiveDocument.Selection.StartOfLine
ActiveDocument.Selection.EndOfLine dsExtend
if LTrimTabs(ActiveDocument.Selection) <> "" then
exit do
end if
ExecuteCommand "LineCut"
' Make sure we haven't hit the bottom of the file
ActiveDocument.Selection.EndOfDocument
if ActiveDocument.Selection.CurrentLine = nCurrentLine + 1 then
exit do
end if
ActiveDocument.Selection.MoveTo nCurrentLine + 1, 1
loop
ActiveDocument.Selection.MoveTo nCurrentLine, nCurrentColumn
end if
wend
strLastPos = InitializePosition
' Remove any blank lines right above any closing braces ("}")
while ActiveDocument.Selection.FindText("}") and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the action since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText "}"
ActiveDocument.Selection.CharLeft
' Cut blank lines above the }
do while true
ActiveDocument.Selection.LineUp
ActiveDocument.Selection.StartOfLine
ActiveDocument.Selection.EndOfLine dsExtend
if LTrimTabs(ActiveDocument.Selection) <> "" then
if ActiveDocument.Selection.CurrentLine > 1 then
ActiveDocument.Selection.LineDown
end if
ActiveDocument.Selection.StartOfLine
ActiveDocument.Selection.FindText "}"
strLastPos = ActiveDocument.Selection.CurrentLine & "," & _
ActiveDocument.Selection.CurrentColumn
ActiveDocument.Selection.LineDown
ActiveDocument.Selection.StartOfLine
exit do
end if
ExecuteCommand "LineCut"
loop
end if
wend
end function
' Remove all spaces and tabs found in the current selection
function RemoveSpacesInSelection
dim iPos, ch, strNoSpaces
for iPos = 1 to Len(ActiveDocument.Selection)
ch = Mid(ActiveDocument.Selection, iPos, 1)
if ch <> " " and ch <> vbTab then
strNoSpaces = strNoSpaces + ch
end if
next
ActiveDocument.Selection = strNoSpaces
end function
' Fix any code with exponential notation (ie. 3.4e-2) which was
' broken when the + and - operators were fixed above (by FixOperator).
function FixExponents
while ActiveDocument.Selection.FindText("[0-9,\.]e [\+\!\-] [0-9]", _
dsMatchRegExp)
RemoveSpacesInSelection
wend
end function
' Break any lines containing multiple statements (separated by semicolons)
function BreakLinesWithMultipleStatements()
dim strLastPos, nCurrentLine
strLastPos = InitializePosition
' Search for multiple semicolons on the same line
while ActiveDocument.Selection.FindText(";.+;", dsMatchRegExp) and _
GetCurrentPosition(strLastPos)
' Check if we're inside a comment or between quotes
if not ShouldIgnore then
' Repeat the action since ShouldIgnore puts the cursor at the
' beginning of the line
ActiveDocument.Selection.FindText ";.+;", dsMatchRegExp
nCurrentLine = ActiveDocument.Selection.CurrentLine
ActiveDocument.Selection.CharLeft
ActiveDocument.Selection.StartOfLine dsFirstText, dsExtend
' If found, check that the semicolons don't belong to a for loop
if (InStr(1, ActiveDocument.Selection, "for (", _
vbTextCompare) > 0) then
ActiveDocument.Selection.MoveTo nCurrentLine + 1, 1
else
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.CharRight
ActiveDocument.Selection.NewLine
end if
end if
wend
end function
Sub MakeSelectedCodeNicer()
'DESCRIPTION: Reformats the currently selected source code to look nicer.
' Written by Alvaro Mendez on 07/15/1999
' Check if there's a valid selection
if ActiveDocument.Selection = "" then
exit sub
end if
' Copy the selection to the clipboard
ActiveDocument.Selection.Copy
' Open a new document and changed its language to C/C++
' This is required for SmartIndent to work.
Documents.Add "Text"
ExecuteCommand "Properties"
ActiveDocument.Language = "C/C++"
' Paste the selection into the document and run the macro
ActiveDocument.Selection.Paste
ExecuteCommand "MakeCodeNicer"
' Select the resulting code and copy it to the clipboard
ActiveDocument.Selection.SelectAll
ActiveDocument.Selection.Copy
' Close the new document (without saving it)
ActiveWindow.Close dsSaveChangesNo
' Paste the reformatted code back over the original selection
ActiveDocument.Selection.Paste
End Sub

Comments