Indenting source code
From Vim Tips Wiki
Tip 83 Previous Tip • Next Tip
Created: June 22, 2001 Complexity: basic Author: Eugene Huang Minimum version: 5.7 Karma: 1826/649 Imported from: Tip#83
The indent features of Vim are very helpful for indenting source code.
Contents |
[edit] Setup
To make indentation work nicely I have the following in my vimrc:
set et set sw=4 set smarttab
These make Vim behave nicely when indenting, giving 4 spaces (not tabs) for each "tabstop".
[edit] How to use
- Type == to indent the current line.
- Press V then move the cursor to select a range of lines. Then == will indent your selection.
- Type a number then == will indent that many lines, starting from your cursor.
There are many other things you can do to select a range of lines and indent them.
If auto-indenting causes problems when pasting in a terminal, see Toggle auto-indenting for code paste.
[edit] See also
TO DO
- Merge some of following tips.
- Need info on commands like vaB, viB, >aB, >iB.
[edit] Indenting code
- 83 Indenting source code
- 221 Indenting Java throw statements
- 247 Preexisting code indentation
- 597 Indent a code block
- 668 Re-indenting sections
- 700 Indenting for Java
- 909 Easy indenting in insert and normal mode with no cursor displacement
- 1213 Better indent support for php with html
- 1231 Set indent parameters for Python files
- 1269 Indent text object
[edit] Auto indent
- 330 How to stop auto indenting
- 522 Fix an autoindent error
- 551 Automatically indent an XML file using XSLT
- 644 Restoring indent after typing hash
- 906 Toggle auto-indenting for code paste
- 1019 Keep indent for new lines
- 1039 Disable auto indenting yet keep imaps
- 1124 Turn off per-filetype auto indentation
- 1327 Prevent autoindent from removing indentation
[edit] Other
- 103 Move to next/previous line with same indentation
- 112 Back and forth between indented lines again
- 477 Put the indentation level on the status line
- 1014 Visual selection of indent block
- 1168 Folding for plain text files based on indentation
[edit] Comments
The "=" command operates on lines ranges in the same way as "d", "y", ">". This duplicates the functionality of typing your code in the first place after using the ":set autoindent" command. HOWEVER, it is far preferrable to use ":set noexpandtab tabstop=4 shiftwidth=4" rather than ":set expandtab" since it gives others editing the same code the options of setting the indentation level to 2, 3, 5, 8, ... per personal taste rather than forcing everyone to live with your particular choice. If you prefer your cursor motion to behave as if tabs were actually spaces you can use the virtual edit mode instead. Fortunately the "=" command will allow you to reformat code to include proper tab formatting if someone has made the mistake of using ":set expandtab".
Not to get into a holy way about tabs vs spaces to indent, but I think it's a bit blunt to say 'if someone made the mistake to set :expandtab'. Please read http://www.jwz.org/doc/tabs-vs-spaces.html for a whole discussion on why spaces are better.
Go tabs! http://derkarl.org/why_to_tabs.html
To unindent you can do this:
Select (in any way you choose) the lines you want to unindent, and then type <<. You can do this repeatedly until everything is unindented.
(Also >> indents manually one tab stop)
To indent all your code, you can type 'gg=G'; 'gg' to go to the top of the file and '=G' to indent from the current line to the last. 'G=gg' also works...
to indent the whole file without having the cursor move to the beginning or the end I have the following function and mapping:
fun BenIndent()
let oldLine=line('.')
normal(gg=G)
execute ':' . oldLine
endfun
map -- :call BenIndent()<cr>
Just hit -- (conveniently close to ==) in normal mode to indent the whole file.
Vim 6.0 has a new "flexible indenting" feature so that indenting works in many different programming languages and filetypes. To turn it on automatically for built-in filetypes, just add:
filetype indent on
to your vimrc. See :help new-indent-flex and :help 'indentexpr' for more details.
You can use pretty much any selection method for indent "="
- To indent within braces do " =%"
- To indent a block, select the beginning of the block by placing a bookmark e.g. " ma" where a is the name of the buffer (any character)
scroll to the end of the block and do " ='a " - Multiple lines, "n==" where n is the number of lines
I have to put in a plug for a script someone submitted that helps with the whole tabs/spaces indenting thing. script#513
Upon loading a buffer, a python script looks through the file, determines what indent style was used, then adjusts your settings so that new modifications use that same style.
I have found in :help 'tabstop' four main ways of indent my code. I have this on my vimrc and works perfect for me:
set noexpandtab set softtabstop=4 set tabstop=8 set shiftwidth=4 set foldmethod=indent
That is:
- Don't replace TAB character with only spaces
- Use a mix of tabs and spaces when I press the TAB key (width 4)
- Default setting of tabstop as recommended in help (width 8) -- printing, etc
- Number of spaces to use for each step of indent (width 4)
- Lines with the same indent level form a fold
See help pages for each setting and :help ins-expandtab for more help.
One way to do indent many files is to use the argument-list:
:args *.c :argdo exe "normal 1G=G" | update
I've been looking for a way to easily (but manually) indent blocks of code, for if I paste a control statement into a buffer, etc. With guidance from comments above, this is what I've come up with- I put these lines in my .vimrc file:
"indent/ unindent "Do this by hitting the mapped key, then clicking the bottom of the block "that you want indented. map <F4> > map! <F4> <ESC><F4> map <F5> < map! <F5> <ESC><F5>
Put the cursor on the first line you want indented. Hit F4, then click the end of the code you want to indent and it will indent the whole block by one tab. Hitting F5 will un-indent one tab the same way. Super easy.
For "normal" tab and shift-tab behavior:
map <Tab> >0 map <S-Tab> <0 imap <S-Tab> <Esc> < i
While you're here reading about tabs and spaces I thought you might want to hear about :insert. For example, if you normally paste into a terminal window some code from some other gui window, Vim will indent the paste as if you typed it, which turns out bad on already indented code. So, you may want to re-indent the file using one of the methods above. But, if you remember to do the following before you paste you may not need to re-indent: do <Esc>:insert<cr> and then paste (however your gui pastes into the terminal) and then press <Esc> more to say you're done pasting.
Sorry if someone feels that's off topic, but I think it's still in the realm of indentation issues.
:set paste also allows you to paste
When I use '==' in command mode it unindents the selected line instead of indenting it. Any Ideas on how to fix this? The commands '>>' and '<<' work, the former unindents and the latter indents, but I cannot indent multiple lines with these commands.
To do this in multiple files as asked above,
:set autowrite :bufdo :%=
As mentioned above ":%=" doesn't work. ":h :=" also tells why. So you have to use "bufdo normal gg=G" to reindent all open buffers.
To indent the whole buffer, you don't have to write a new function "map -- gg=G" does the same (see also ":h ").
I was using "map <c-i> ma1G=G'a" however the command above I can use without messing up my marks
and you can do another neat thing, but becareful to not use it while remote editing. It produces a lot of traffic for slow connection...also i have not tested this because i only edit locally. You can tell Vim to reindent the whole file every time you press enter in insert-mode. I want this only for my c source files so i put the following line into ~/.vim/ftplugin/c.vim
imap <silent> <CR> <ESC>gg=G<C-O><C-O>o
after reading here i changed it to:
imap <silent> <CR> <ESC>=a{<C-O>o
i think its more than enough to keep the current block indented. And as i use the above only for c-files it fits perfect.
I have been using "==" for indenting. The problem comes when all comment line starting with "#" go to the first column.
Before formatting
{
# Do something here.
set a 10;
}
After formatting.
{
# Do something here.
set a 10;
}
Is there any way to give the same indent for comments and code.
This is possible by e.g. setting
set cinkeys=0{,0},!^F,o,O,e
By default, "0#" is also included in this list. That moves all lines starting with '#' to the first column (pretty common for C code, pretty ugly for perl). See ":help cinkeys-format".
See VimTip906 to avoid the problem in a console that when you paste code you see:
a=0;
b=0;
c=0;
Categories: Review | VimTip | Indenting | Todo
