Is it possible to format C++ code with VIM?
Asked Answered
C

9

37

I am rather new to VIM. I got some source code and this is a mess. At a first sight I would like at least to get a clear and organised view of the code, so I like to get it rightly formatted, I mean indented depending on the depth of the functions and so.

I wonder if it can be done with VIM, and otherwise which other commandline tools for that can you recommend.

Thanks

Clerc answered 24/3, 2010 at 10:15 Comment(0)
A
66

While vim is a true Swiss-knife I still prefer external tools for some jobs. This approach is some times much more intuitive and easy to remember than using the built-in equivalent.

In the case of indenting, I filter the whole file buffer through astyle. The astyle parameters are much easier to grasp in a couple of minutes, especially if you are not a vim guru. Also astyle provides much more flexibility in fine-tuning the output.

First install astyle:
# apt-get install astyle

Then inside vim:
:%!astyle (simple case - astyle default mode is C/C++)
or
:%!astyle --mode=c --style=ansi -s2 (ansi C++ style, use two spaces per indent level)
or
:1,40!astyle --mode=c --style=ansi (ansi C++ style, filter only lines 1-40)

Amalea answered 24/3, 2010 at 10:44 Comment(2)
Is it possible to map this to a key combination like ctrl+shift+F?Shoeshine
You can also override Vim's indent operator (=) to use Astyle by setting equalprg to astyle (e.g: set equalprg=~/astyle\ --style=google)Hauger
B
37

you can do the following:

gg=G
Baecher answered 24/3, 2010 at 10:18 Comment(3)
To clarify, =[motion] indents the region encompassed by the motion. gg moves to the beginning of the file and G moves to the end of the file.Mccalla
or start with V to enter visual line mode, then move down with j to select all the lines you want to format, then hit =Jameson
I don't like gg=G. Why? Because when you break long list with commas (argument list, long booleans) it will break manual alignment.Muncy
P
19

I would highly recommend clang-format nowadays. It allows simple integration of clang-format into Vim, once you have clang-format installed:

http://clang.llvm.org/docs/ClangFormat.html#vim-integration

It is the only code beautifier that really understands your C++ code, and it is really intelligent to beautify the code more like a human being than a machine. E.g.:

void TestFunction(int argument1, int argument2,
                  int argument3);
void TestFunctionVeryLongName(int argument1,
                              int argument2,
                              int argument3);
void TestFunctionWithRidiculouslyLongName(
    int argument1, int argument2, int argument3);
Pinchpenny answered 8/1, 2015 at 8:22 Comment(1)
An alternative to the keybindings suggested in the clang-format manual is to use the equalprg binding in vim. This allows you to invoke clang-format with G=gg or other = indent options. Just put the following in your .vimrc file: autocmd FileType c,cpp setlocal equalprg=clang-formatIntern
E
5

Vim will definitely do this, although the results may not be perfect:

  1. First, select the entire file in visual mode: ggVG
  2. Then hit = to reindent everything.

You can learn more about the equal command with: :help =

Elevator answered 24/3, 2010 at 10:19 Comment(0)
P
5

There is a vim plugin that enables formatting on your code from within vim. It's called vim-autoformat and you can download it here:

https://github.com/vim-autoformat/vim-autoformat

It integrates external code-formatting programs into vim. For example, if you want to format C, C++, C# or Java code, you need to install the program astyle, and vim sets it as the format program automatically.

Polynesia answered 3/12, 2012 at 20:29 Comment(0)
P
4

There is also a Vim plugin relying on clang-format: vim-clang-format

Then you can simply map the formatting command to whatever suits you.

Porcelain answered 7/10, 2014 at 18:17 Comment(0)
C
2

I don't write C++ code, but I write some Java code.

Instead, Vim supports the formatting of some common languages. I have set up a short cut for me to format the whole code in the buffer. It will return to the line I just edited :)

" format the file
map <leader>fm gg=G'. 
Christianism answered 22/12, 2012 at 17:48 Comment(0)
B
1

A generic solution along the lines of m000's idea is to use UniversalIndentGUI as an external tool.

Brakpan answered 24/3, 2010 at 13:7 Comment(1)
thanks for the info, but i prefer VIM because i have to debug code on remote machinesClerc
C
0

Just had to solve this exact problem, so I thought I'd contribute to save others some time.

You can use gg=G to indent your code. But things get hard to understand the moment you want to tweak how that auto-indenting happens. Therefore, if you only care that errant whitespace is removed and don't really care about formatting style, gg=G is the quickest way to go about it, because its built-in.

If you do want to control the style (for example, you're trying to make your code conform to a style guide), then you're going to need an external tool to process your file. You can invoke that tool from within vim with: :%!<toolname> <options>. This pipes the file through the tool and re-loads the processed result. (You can obviously use this for anything else you want to do to your file too)

So the next question is, what external tool should you choose? Regardless, the method is the same:

  1. Install the tool of choice
  2. Make sure its in your path
  3. Add a line to your vimrc file that creates a shortcut key to use so you save time
  4. Use it.

Now, which tool you use depends on the style you're trying to replicate. If you're trying to replicate a widely used style, then chances are astyle is all you need.

If you're trying to replicate a custom style, then you will need two things:

  1. UniversalIndentGui - a front end that lets you play around with various options and live-preview their effect on the source file
  2. A set of source code formatting tools installed and in your path

Between uncrustify and greatcode, you should be able to completely replicate the style you want.

Actually, I lied. There is another way and its called clang-format. However, you're going to want to read the documentation on it and its still in early stages so some options don't work very well. It is a beautiful tool though (definitely the smartest of the lot because constructs an AST of your code) and it is even available for Windows.

If you're going to take the time to read the manual, you also want to check out GNU Indent.

Of course, there is the last way, which is actually taking the time to learn vim's indent rules and writing one for your style. It will take time, but it will work with gg=G.

Some notes on astyle vs uncrustify vs greatcode:

  1. Astyle is good for general formatting, but can't do things like align the declaration of variables and re-style comments very well.
  2. Uncrustify can do a LOT of stuff that astyle can't, but be prepared to spend an hour playing around until you've found the correct combination of options you need. (Or if you feel like wasting a lot of time, use genetic algorithms to figure out the best combination of options for your style and when you do share the code and give me a link so I can use it too :) )

Note that you don't have to choose one tool. With vim, you can map one keystroke to execute several commands in succession, so theoretically you could use a combination of these tools to get exactly what you're looking for.

Last but not least, here's an excerpt from my .vimrc file, where I have mapped F12 to invoke astyle with some options:

"A2 = attached brackets
"-s8 indent 8 spaces
"-xc attached braces to class declarations
"-xj remove braces for single statement ifs and elses
"-c convert tabs to spaces in the non-indentation part of the line
map <F12> :%!astyle -A2 -s8 -xc -xj -c<CR>

Don't judge me on the style. Just use the tool to reproduce what you want.

Cristacristabel answered 9/7, 2014 at 21:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.