*04* Automatic indenting C/C++ programs This chapter tells how to tune vim for auto-indentation of C/C++ programs. |04_1| Indenting C/C++ programs |04_2| Setting indent style |04_3| Tabs and spaces |04_4| Navigating a C/C++ file |04_5| Some other useful commands =========================================================================== *04_1* Indenting C/C++ programs A program is much easier to understand when the lines have been properly indented. Vim offers various ways to make this less work. For C programs set the 'cindent' option. Vim knows a lot about C programs and will try very hard to automatically set the indent for you. Set the 'shiftwidth' option to the amount of spaces you want for a deeper level. Four spaces will work fine. One ":set" command will do it: > :set cindent shiftwidth=4 With this option enabled, when you type something such as "if (x)", the next line will automatically be indented an additional level. if (flag) Automatic indent ---> do_the_work(); Automatic unindent <-- if (other_flag) { Automatic indent ---> do_file(); keep indent do_some_more(); Automatic unindent <-- } When you type something in curly braces ({}), the text will be indented at the start and unindented at the end. The unindenting will happen after typing the '}', since Vim can't guess what you are going to type. One side effect of automatic indentation is that it helps you catch errors in your code early. When you type a } to finish a function, only to find that the automatic indentation gives it more indent than what you expected, there is probably a } missing. Use the "%" command to find out which { matches the } you typed. A missing ) and ; also cause extra indent. Thus if you get more white space than you would expect, check the preceding lines. If you want some extra indentation, you can always do the following in insert mode to insert an extra indent at the beginning of the line, no matter where you are > Similarly, you can type the following to decrease the indent > The similar operators in normal mode are '>' and '<'. As per convention the following increase and decrease the indent of the current line > >> << When you have code that is badly formatted, or you inserted and deleted lines, you need to re-indent the lines. The "=" operator does this. The simplest form is: > == This indents the current line. Like with all operators, there are three ways to use it. In Visual mode "=" indents the selected lines. A useful text object is "a{" This selects the current {} block. Thus, to re-indent the code code block the cursor is in: > =a{ I you have really badly indented code, you can re-indent the whole file with: > gg=G However, don't do this in files that have been carefully indented manually. The automatic indenting does a good job, but in some situations you might want to overrule it. =========================================================================== *04_2* Setting indent style Different people have different styles of indentation. By default Vim does a pretty good job of indenting in a way that 90% of programmers do. There are different styles, however; so if you want to, you can customize the indentation style with the 'cinoptions' option. By default 'cinoptions' is empty and Vim uses the default style. You can add various items where you want something different. For example, to make curly braces be placed like this: if (flag) ~ { ~ i = 8; ~ j = 0; ~ } ~ Use this command: > :set cinoptions+={2 Here the '}' applies the indentation (2 spaces) to all opening braces that are inside other braces. Each of the sub-options are of the type > cS where 'c' is the character where the indentation should apply. While S specifies the indentation. S can take many forms, some of which are shown in table below 2 increase by 2 spaces -2 decrease by 2 spaces s increase shiftwidth spaces .5s increase by 1/2 shiftwidth spaces. Note: In some cases, S denotes the absolute position and not the increase. An example setting of cinoptions is > set cinoptions=s,e0,n0,f0,{0,}0,^0,:s,=s,g0,hs,ps,t0,+s,(0,)20,*50 Look through the help pages for all the sub-options. Another option which affects when the indentation is done is 'cinkeys'. The default is generally acceptable. Go through the help pages for this option also. Comments style ~ One of the great things about Vim is that it understands comments. You can ask Vim to format a comment and it will do the right thing. Suppose, for example, that you have the following comment: /* ~ * This is a test ~ * of the text formatting. ~ */ ~ You then ask Vim to format it by positioning the cursor at the start of the comment and type: > gq]/ "gq" is the operator to format text. "]/" is the motion that takes you to the end of a comment. The result is: /* ~ * This is a test of the text formatting. ~ */ ~ Notice that Vim properly handled the beginning of each line. An alternative is to select the text that is to be formatted in Visual mode and type "gq". To add a new line to the comment, position the cursor on the middle line and press "o". The result looks like this: /* ~ * This is a test of the text formatting. ~ * ~ */ ~ Vim has automatically inserted a star and a space for you. Now you can type the comment text. When it gets longer than 'textwidth', Vim will break the line. Again, the star is inserted automatically: /* ~ * This is a test of the text formatting. ~ * Typing a lot of text here will make Vim ~ * break ~ */ ~ The 'comments' option defines what a comment looks like. Vim distinguishes between a single-line comment and a comment that has a different start, end and middle part. Look through the help pages for more details. =========================================================================== *04_3* Tabs and spaces 'tabstop' is set to eight by default. Although you can change it, you quickly run into trouble later. Other programs won't know what tabstop value you used. They probably use the default value of eight, and your text suddenly looks very different. Also, most printers use a fixed tabstop value of eight. Thus it's best to keep 'tabstop' alone. For indenting lines in a program, using a multiple of eight spaces makes you quickly run into the right border of the window. Using a single space doesn't provide enough visual difference. Many people prefer to use four spaces, a good compromise. Since a is eight spaces and you want to use an indent of four spaces, you can't use a character to make your indent. There are two ways to handle this: 1. Use a mix of and space characters. Since a takes the place of eight spaces, you have fewer characters in your file. Inserting a is quicker than eight spaces. Backspacing works faster as well. 2. Use spaces only. This avoids the trouble with programs that use a different tabstop value. Fortunately, Vim supports both methods quite well. Spaces and tabs ~ If you are using a combination of tabs and spaces, you just edit normally. The Vim defaults do a fine job of handling things. You can make life a little easier by setting the 'softtabstop' option. This option tells Vim to make the Tab key look and feel as if tabs were set at the value of 'softtabstop', but actually use a combination of tabs and spaces. After you execute the following command, every time you press the Tab key the cursor moves to the next 4-column boundary: > :set softtabstop=4 When you start in the first column and press , you get 4 spaces inserted in your text. The second time, Vim takes out the 4 spaces and puts in a (thus taking you to column 8). Thus Vim uses as many s as possible, and then fills up with spaces. When backspacing it works the other way around. A will always delete the amount specified with 'softtabstop'. Then are used as many as possible and spaces to fill the gap. The following shows what happens pressing a few times, and then using . A "." stands for a space and "------->" for a . type result ~ .... -------> ------->.... -------> .... An alternative is to use the 'smarttab' option. When it's set, Vim uses 'shiftwidth' for a typed in the indent of a line, and a real when typed after the first non-blank character. However, doesn't work like with 'softtabstop'. Just spaces ~ If you want absolutely no tabs in your file, you can set the 'expandtab' option: > :set expandtab When this option is set, the key inserts a series of spaces. Thus you get the same amount of white space as if a character was inserted, but there isn't a real character in your file. The backspace key will delete each space by itself. Thus after typing one you have to press the key up to eight times to undo it. If you are in the indent, pressing CTRL-D will be a lot quicker. Changing tabs in spaces (and back) ~ Setting 'expandtab' does not affect any existing tabs. In other words, any tabs in the document remain tabs. If you want to convert tabs to spaces, use the ":retab" command. Use these commands: > :set expandtab :%retab Now Vim will have changed all indents to use spaces instead of tabs. However, all tabs that come after a non-blank character are kept. If you want these to be converted as well, add a !: > :%retab! This is a little bit dangerous, because it can also change tabs inside a string. To check if these exist, you could use this: > /"[^"\t]*\t[^"]*" It's recommended not to use hard tabs inside a string. Replace them with "\t" to avoid trouble. The other way around works just as well: > :set noexpandtab :%retab! =========================================================================== *04_4* Navigating a C/C++ file There are many commands which help you navigate a C/C++ file faster. If you want to go to the start of the next function, you can use the command > ]] Note: Actually this is to the next '{' in the first column. Similarly to go to the start of the last function, you can use > [[ You can also use the following > ][ (forward to next end of function) [] (backward to next end of function) Remember, the first ']' or '[' specifies the direction. The other useful navigation commands are > % Go to matching (), {}, [], /* */, #if, #else, #endif. [/ Go to previous start of comment. ]/ Go to next end of comment. [# Go back to unclosed #if, #ifdef, or #else. ]# Go forward to unclosed #else or #endif. [( Go back to unclosed '(' ]) Go forward to unclosed ')' [{ Go back to unclosed '{' ]} Go forward to unclosed '}' < =========================================================================== *04_5* Some other useful commands Listing included files ~ Suppose you are editing a file and you want to know the list of all included files, you can type > :che[ckpath]! Note: This and the following commands depends on the setting of variable 'path'. Searching a keyword ~ If you want to search for a keyword in your current and included files, you can type > [i This gives the first match. If you want to list all the matches, you can type > [I If you just want to search for defines, you can use the following commands > [d [D Going to the keyword ~ You can use the following command to jump to the local declaration of the variable under cursor > gd Similarly, you can use the following for global declaration > gD To jump to the file under cursor, type > gf Note: This can be used anywhere, not just C/C++ files. =========================================================================== vim:ft=help:tw=76:ts=8:nomodifiable