Click here to Skip to main content
15,860,859 members
Articles / Programming Languages / C++
Article

Reformat source code

Rate me:
Please Sign up or sign in to vote.
4.97/5 (34 votes)
26 Sep 20055 min read 407.4K   3.8K   82   127
A great macro for reformatting C++ source code.

Introduction

MakeCodeNicer began as a Visual C++ 6.0 macro used for reformatting C/C++ source files on the fly, right inside the editor. It was used by developers who needed to quickly reformat source files (usually written by other people) for their own use.

Visual Studio 2002 and 2003 introduced a new macro engine, which unfortunately broke MakeCodeNicer. Anders Dalvander was kind enough to convert the code so that it would compile, but for some reason, it didn't quite work as expected.

Well, I've finally taken some time to finish Anders' port so that this macro can once again be used inside Microsoft's development environment. I'm going to keep the VC6 version available for download, but since I don't have VC6 installed, I can't support that version any more.

Installation

To install the VS.NET version:

  1. For 2003, extract the zip file to your "My Documents\Visual Studio Projects\VSMacros71\". (For 2005 and later, please see the Notes section below.) Be sure to "Use folder names" when extracting.
  2. Inside Visual Studio, go to Tools/Macros/Load Macro Project.
  3. Select the ReformatCode.vsmacros file (inside the ReformatCode folder).
  4. In the Macro Explorer, expand the ReformatCode module and then the MakeCodeNicer macro.
  5. You'll see the SelectionOnly and WholeFile methods.
  6. Open a C, C++, C#, Java, or JavaScript source file to be reformatted. Make sure it compiles successfully!
  7. If you want the whole file to be reformatted, double click on the WholeFile method and sit back to let it do its thing. While it's running, you'll see an animated cassette in the system tray, which can be right-clicked to interrupt the macro.
  8. If you only want to reformat a portion of the file, select the portion, and double click on the SelectionOnly method.

What it does

Once the macro is done, you'll see that it does several things to your source code:

  • Adds extra spaces in a few places and removes them from other places:
    • Appends a space to if, for, foreach, while, switch, catch, return, throw, lock, and using statements.
    • Removes any spaces before or after method parenthesis.
    • Adds a space before and after operators (such as =, ==, etc.).
    • Appends a space to commas and semicolons (inside for loops).
    • Inserts a space between the // and the first character of inline comments.
  • Breaks single-line if, for, foreach, and while statements into multiple lines (for easier debugging).
  • Breaks up case statements into their own lines and indents them if necessary.
  • Isolates braces ({ }) into lines by themselves.
  • Removes trailing white space from all lines in the file.
  • Removes extraneous blank lines.
  • Accounts for code within quoted strings or characters.
  • Ignores code after inline comments (//).

If you've worked with MFC in the past and followed its conventions, you'll no doubt recognize this macro's formatting. It's clean and very easy to read, in my opinion.

Notes

I ported and tested this macro using C# source files, but it should work with any of the C-derived languages. If you find any problems, please let me know.

I'm also happy to report that Visual Studio .NET 2005 finally makes this macro obsolete. If you need to reformat source code, simply press Ctrl+E, D and the file will be reformatted according to your settings (inside Tools/Options - Text Editor/Language/Formatting).

Enjoy it!

Updates

5 May 2000

  • Fixed cases when code gets incorrectly unindented if one or more curly braces appear inside quoted strings. (Thanks to Bob Eastman for reporting it.)
  • Fixed cases when "operator=(...)" turns into "operator =(...)".
  • Added more up-front validations to ensure the macro can be run properly.
  • Made the macro execute on a temporary file which is then copied onto the target source code. This allows undoing of all of the macro's changes in one step. (Thanks to Nicolas Fleury for suggesting it.)

16 Feb 2001

  • Added a check for Visual C++'s "out of memory" bug which occurs when the macro is invoked on multiple very-large source files. (Thanks to Aaron Sulwer for reporting and helping me test this problem.)
  • Added code to remove spaces before and after -> operators. (Thanks to Dominic Holmes for suggesting it.)
  • Fixed erroneous space removals before certain opening parenthesis and after inlined functions. (Thanks to Joe Woodbury for reporting these.)

26 Apr 2001

  • Changed the logic that fixes less than and greater than operators to only do so when they're inside "for", "while", and "if" statements. Since these operators have so many uses in C++, it's very difficult to accurately fix them across the board. Thanks to Robin Summerhill and Thomas Freudenberg for bringing these to my attention.
  • Replaced Int() with CInt() in two locations. This should prevent a type mismatch error reported by Henning Flessner.

9 July 2002

  • Stopped multi-line preprocessor macros from being reformatted. (Thanks to Niels Harremoës for reporting it.)
  • Fixed improper splitting of lines with multiple semicolons. (Thanks to Jon for reporting it.)
  • Adjusted the FILE DESCRIPTION comment to allow the macro's description to be displayed on the "Add-ins and Macro Files" tab of the Customize box. (Thanks to Michael Martin for reporting it.)

15 Jul 2002

  • Fixed possible Type Mismatch error. (Thanks to henning flessner for reporting it and providing the solution.)
  • Stopped code containing "','," from turning into "', ',". (Thanks to Dirk for reporting it.)

16 Aug 2005

  • Ported to Visual Studio .NET 2003. Thanks to Anders Dalvander for giving me a great jump start in the effort.
  • I converted all variables to be type specific to improve performance. I also created a local variable in most methods to cache the ActiveDocument.Selection.
  • I fixed several minor issues, thanks to the new ability to debug (woo hoo).

15 Sep 2005

  • Fixed conversion of < and > operators when used for template notation. (Thanks to Eddie Parker for reporting the problem.)
  • Ported to Visual Studio .NET 2005 (Beta 2). Now all it does is run the "SmartFormat" method (which can easily be invoked with Ctrl+E, D). This macro has finally become obsolete. :-)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I've done extensive work with C++, MFC, COM, and ATL on the Windows side. On the Web side, I've worked with VB, ASP, JavaScript, and COM+. I've also been involved with server-side Java, which includes JSP, Servlets, and EJB, and more recently with ASP.NET/C#.

Comments and Discussions

 
Generalnice macro Pin
ralucamorosan14-Apr-07 20:59
ralucamorosan14-Apr-07 20:59 
GeneralRe: nice macro Pin
alex_vara1-Nov-07 14:56
alex_vara1-Nov-07 14:56 
Generalsweet Pin
j_l_larson3-Jan-07 11:11
j_l_larson3-Jan-07 11:11 
Generalblock instruction { } Pin
Stewenson29-Sep-06 1:30
Stewenson29-Sep-06 1:30 
Generaldecrement operator issue Pin
Andreas Schoenle21-Mar-06 4:41
Andreas Schoenle21-Mar-06 4:41 
GeneralNice! but still has room to refine. Pin
min_2_max18-Oct-05 3:16
min_2_max18-Oct-05 3:16 
General#region/#endregion Pin
macleod564-Oct-05 17:07
macleod564-Oct-05 17:07 
GeneralRe: #region/#endregion Pin
Alvaro Mendez5-Oct-05 14:22
Alvaro Mendez5-Oct-05 14:22 
NewsAlternative Pin
Pandele Florin27-Sep-05 23:21
Pandele Florin27-Sep-05 23:21 
GeneralRe: Alternative Pin
Alvaro Mendez28-Sep-05 14:22
Alvaro Mendez28-Sep-05 14:22 
GeneralLooks like my code is already pretty nice Pin
ComputerGuyCJ27-Sep-05 11:39
ComputerGuyCJ27-Sep-05 11:39 
GeneralError during Add Document Pin
rh27-Sep-05 2:18
rh27-Sep-05 2:18 
GeneralRe: Error during Add Document Pin
Alvaro Mendez28-Sep-05 14:26
Alvaro Mendez28-Sep-05 14:26 
GeneralRe: Error during Add Document Pin
RuslanKulubaev9-Jul-07 21:59
RuslanKulubaev9-Jul-07 21:59 
GeneralProblem on var declaration Pin
Stephan Pilz26-Sep-05 19:35
Stephan Pilz26-Sep-05 19:35 
QuestionTemplates &amp; For Loops? Pin
Member 227599414-Sep-05 11:49
Member 227599414-Sep-05 11:49 
QuestionHow about this? Pin
Matt Godbolt14-Sep-05 7:23
Matt Godbolt14-Sep-05 7:23 
GeneralRemoval of &quot;non&quot; blank blank lines Pin
Jim Fougeron30-Apr-04 9:26
sussJim Fougeron30-Apr-04 9:26 
GeneralHandling c++ and c multiline comments Pin
Member 86675722-Apr-04 9:00
Member 86675722-Apr-04 9:00 
GeneralRe: Handling c++ and c multiline comments - correction Pin
Member 86675722-Apr-04 9:10
Member 86675722-Apr-04 9:10 
PRIVATE FUNCTION IsWithinComment

DIM nCurrentLine, nCurrentColumn
DIM nBeginCommentLine, nBeginCommentColumn
DIM nEndCommentLine, nEndCommentColumn

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

nCurrentLine = nCurrentLine + 1
END IF

ActiveDocument.Selection.MoveTo nCurrentLine, nCurrentColumn

IF not IsWithinComment THEN
' Now look to see if we are in a c multiline comment, we do this by simply looking
' from out current position to the beginning of the file for "/*" '

ActiveDocument.Selection.FindText "\/\*", dsMatchCase + dsMatchBackward + dsMatchWord _
+ dsMatchRegExp

IF bContinue THEN
nBeginCommentLine = ActiveDocument.Selection.CurrentLine
nEndCommentColumn = ActiveDocument.Selection.CurrentColumn

' Look forward for the matching "*/" '

ActiveDocument.Selection.FindText "\*\/", dsMatchCase + dsMatchForward + dsMatchWord _
+ dsMatchRegExp

nEndCommentLine = ActiveDocument.Selection.CurrentLine
nEndCommentColumn = ActiveDocument.Selection.CurrentColumn

IF nBeginCommentLine <= nCurrentLine and _
nBeginCommentColumn < nCurrentColumn and _
nEndCommentLine >= nCurrentLine and _
nEndCommentColumn > nCurrentColumn THEN
IsWithinComment = true
END IF

END IF

ActiveDocument.Selection.MoveTo nCurrentLine, nCurrentColumn

END IF

END FUNCTION ' IsWithinComment'

Sean C. Hubbell
GeneralRe: Handling c++ and c multiline comments - correction - correction Pin
Member 86675722-Apr-04 9:19
Member 86675722-Apr-04 9:19 
GeneralPorted to VS.NET 7.1 (long post) Pin
Anders Dalvander17-Jul-03 23:50
Anders Dalvander17-Jul-03 23:50 
GeneralRe: Ported to VS.NET 7.1 (long post) Pin
Joe Woodbury22-Aug-03 8:43
professionalJoe Woodbury22-Aug-03 8:43 
GeneralRe: Ported to VS.NET 7.1 (long post) Pin
Anonymous17-Mar-04 3:08
Anonymous17-Mar-04 3:08 
GeneralRe: Ported to VS.NET 7.1 (long post) Pin
Yuh-Rong Leu16-Mar-05 4:36
sussYuh-Rong Leu16-Mar-05 4:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.