75

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?

chrisjlee
  • 8,523
  • 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. – Edd Steel Sep 01 '11 at 22:37
  • ideally Html/css and php – chrisjlee Sep 01 '11 at 23:50

9 Answers9

128

To indent the whole file automatically:

gg
=G

Explained:

  • gg - go to beginning of the file
  • G - go to end of the file
  • = - indent
takeshin
  • 1,743
  • 2
    Could you break it down? What is g typically by itself? and =G? – chrisjlee Sep 02 '11 at 05:47
  • 1
    @Chris see the edit – takeshin Sep 02 '11 at 05:53
  • 2
    Nice hint, I never knew this. However, it does a rubbish job with bash. – Sparhawk Aug 08 '14 at 04:49
  • How to execute gg=G from shell without opening the file? – W.M. Aug 28 '16 at 16:18
  • @takeshin can you please explain it much further, do we need to type it in the file or do we need to run it in the terminal – Kasun Siyambalapitiya Dec 01 '16 at 11:22
  • To execute that press ESC or CTRL + C and type fast gg=G . You won't see the text but if you were fast, the indent will work. I literally just created an account to explain this to other people. – Merunas Grincalaitis Aug 20 '17 at 11:22
  • I use command :%retab! – michalzuber Aug 26 '17 at 06:50
  • I did not have to type it fast, however, I need indent by two spaces, this uses TAB as indent, sadly, set tabwidth=2 gave me E518: Unknown option, so I did gg, then =G followed by :%s/\t/ /g and got what I needed! (After each I hit return key) – thecarpy Mar 26 '18 at 08:09
  • Major caveat, you have to put filetype plugin indent on in your ~/.vimrc for this to work. Otherwise, gg=G will just left indent every line. See https://unix.stackexchange.com/a/451369 – wisbucky Jun 22 '18 at 18:46
  • @Sparhawk Did you add filetype plugin indent on to your ~/.vimrc? It doesn't work right without that. vim's bash autoformat looked decent to me. – wisbucky Jun 22 '18 at 18:48
  • @wisbucky It's been a while since I posted that comment, so I can't exactly remember the problems. I suspect that it didn't just indent every line though… I think I would have mentioned that (but I'm not 100% sure). – Sparhawk Jun 23 '18 at 01:07
  • Note that to do this, the file being edited seems to need a file extension so that Vim knows how to auto-indent. – jvriesem Jun 03 '20 at 19:45
  • Note that you need filetype plugin indent on enabled to use gg=G – steffres Jul 04 '23 at 11:41
32

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.

enzotib
  • 51,661
Hai Vu
  • 1,201
15

Auto Indent *.sh

Just add the following lines in ~/.vimrc

filetype indent on
set smartindent
autocmd BufRead,BufWritePre *.sh normal gg=G
Rahul Patil
  • 24,711
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.

chtenb
  • 163
2

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

set autoindent
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

wisbucky
  • 3,388
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.

Randall
  • 445
-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

Zibri
  • 573
  • 5
  • 9
  • 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) – eacousineau Mar 02 '17 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). – Roel Van de Paar Apr 18 '20 at 00:55