77

I'm trying to use Vim more and more when I can. One of my biggest grip between Vim and an IDE like Aptana is the ability to auto indent.

Is there a means of auto formatting code (HTML, CSS, PHP) so it is properly indented?

If so how do you install this into vim? I don't understand plugins very much. I tried reviewing this thread and it confused me more: How to change vim auto-indent behavior?

2
  • Could you clarify what language you are trying to indent? I would expect that if it's supported by vim already it should already auto-indent without further effort. If not, you should be able to get a plugin.
    – user4137
    Commented Sep 1, 2011 at 22:37
  • ideally Html/css and php
    – chrisjlee
    Commented Sep 1, 2011 at 23:50

9 Answers 9

132

To indent the whole file automatically:

gg
=G

Explained:

  • gg - go to beginning of the file
  • G - go to end of the file
  • = - indent
13
  • 2
    Could you break it down? What is g typically by itself? and =G?
    – chrisjlee
    Commented Sep 2, 2011 at 5:47
  • 1
    @Chris see the edit
    – takeshin
    Commented Sep 2, 2011 at 5:53
  • 2
    Nice hint, I never knew this. However, it does a rubbish job with bash.
    – Sparhawk
    Commented Aug 8, 2014 at 4:49
  • How to execute gg=G from shell without opening the file?
    – W.M.
    Commented Aug 28, 2016 at 16:18
  • 1
    Note that to do this, the file being edited seems to need a file extension so that Vim knows how to auto-indent.
    – jvriesem
    Commented Jun 3, 2020 at 19:45
35

I don't know about auto-formatting existing code, but if you are writing code and need auto indent:

  • :set autoindent (or :set ai) will turn on auto-indent
  • Ctrl-d to un-indent (AKA outdent) your code
  • Tab or spaces to indent -- I personally use tab
  • :set tabwidth=4 (or :set tw=4) will control how many spaces a tab should indent code
  • The >> command will indent the current line. If you prefix it by a number, say 4>> then it will indent 4 lines, starting with the current line.
  • Likewise the << command will un-indent a line

I hope this gives you a good start.

3
  • 9
    To auto-indent existing code, use ={motion} in normal mode -- e.g. =G will indent all code from the current line to the end of the file. == will indent the current line.
    – user4137
    Commented Sep 1, 2011 at 22:36
  • 1
    also make sure indent plugins are being loaded (e.g. with :filetype indent on)
    – jw013
    Commented Sep 2, 2011 at 0:50
  • 3
    set tw=4 sets the TEXTWIDTH to 4 Commented Apr 25, 2017 at 2:01
18

Auto Indent *.sh

Just add the following lines in ~/.vimrc

filetype indent on
set smartindent
autocmd BufRead,BufWritePre *.sh normal gg=G
4
  • Does this apply only to editing with vim or all editor tools?
    – W.M.
    Commented Aug 28, 2016 at 16:18
  • 1
    ~./vimrc only applicable for vim editor. Commented Aug 29, 2016 at 3:54
  • I've been looking for this for a long time. Thanks.
    – daparic
    Commented Feb 26, 2021 at 18:52
  • could you please explain the last line, autocmd BufRead,BufWritePre *.sh normal gg=G. I need indentation for python, so do I just need to change *.sh to *.py? And it works. Thanks
    – Pro
    Commented May 15, 2022 at 5:16
2

This plugin makes it easier to perform formatting on your code. It integrates external formatters, and has a fallback on vim's indent functionality.

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

Also, notice the difference between formatting and indenting. Indenting only corrects the whitespace before every line, while formatting also deals with any other thing, such as whitespace around operators etc.

2

Create/edit the ~/.vimrc file and add the following line:

set autoindent
3
  • 5
    This adds nothing to the existing answers...
    – jasonwryan
    Commented Jan 30, 2017 at 6:11
  • @jasonwryan Actually Hai Vu's answer mentions :set autoindent which enables auto indent only for the current file. Adding it in the .vimrc file enables auto indent permanently. Commented Jan 30, 2017 at 7:12
  • your piece of comment is already mentioned by Rahul's answer, so think before posting Commented May 8, 2017 at 9:25
1

vim's autoformat/indent works pretty well. First, put this line in your ~/.vimrc:

filetype plugin indent on

Then open a file in vim and type gg=G

(gg moves cursor to the first line. = runs the indent command. G tells indent command to run from here to the last line.)

If the autoformat looks really bad, like every line is just left indented, then run :scriptnames and check if .../indent/html.vim (or whatever language you're using) is in the list. If not, then make sure your ~/.vimrc is correct. Or if you ran :filetype plugin indent on from the vim command line, you will need to re-open the file :e

0

To do a bash script reformat, the gg=G solution proposed does not work well in VIM, irrespective if you set the script to be of shell type. Instead this works;

shfmt -i 2 -ci script.sh

To ident all lines with 2 spaces and do correct otherwise formatting.

0

For a good overview and demo of many of the options mentioned here, Gavin Freeborn has a great video on YouTube:

https://www.youtube.com/watch?v=tM_uIwSucPU

It covers some Vim plugins as well as built-in capabilities such as =, gq, and formatprg.

-1

In bash I do this:

source <(echo "Zibri () {";cat script_to_be_reindented.sh; echo "}")
declare -f Zibri| cut -c 5-|head --lines=-1|tail --lines=+3

this eliminates comments and reindents the script "bash way". it will not work if the script contains HEREDOCS but if you do this:

source <(echo "Zibri () {";cat script_to_be_reindented.sh; echo "}")
declare -f Zibri|head --lines=-1|tail --lines=+3

it will work with any script but the whole script will be indented by 4 spaces. feel free to modify but cite my name in your script and post it! :D

2
  • I believe this may be missing the point of the question; rather than indenting a set of lines, I believe the OP wished to auto-indent within VIM for a variety of languages. As an aside, you may be able to achieve this a little more directly with sed if you so wish: cat script_to_be_reindented.sh | sed 's#^# #g' (er, well, SO markdown is replacing the spaces with a tab, but you get the point) Commented Mar 2, 2017 at 18:29
  • All this answer does is insert spaces in the front of the line and reset all alignment. The same (excluding markdown) can be done with sed -i 's|^[ \t]\+| |' script.sh (that is 4 spaces inside the | | but this website filters multiple spaces into one). Commented Apr 18, 2020 at 0:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .