[html] How do I tidy up an HTML file's indentation in VI?

How do I fix the indentation of his huge html files which was all messed up?

I tried the usual "gg=G command, which is what I use to fix the indentation of code files. However, it didn't seem to work right on HTML files. It simply removed all the formatting.

I also tried setting :filetype = xml, to see if tricking it into thinking this was an XML file would help but it still didn't do it.

This question is related to html vim vi indentation

The answer is


Have you tried using the HTML indentation script on the Vim site?


Here's a heavy-weight solution that gets you indenting, plus all the HTML pretty-printing you don't necessarily want to care about while you're editing.

First, download Tidy. Make sure you add the binary to your path, so you can call it from any location.

Next, create a config file describing your favorite HTML flavor. Documentation is not great for Tidy, but here's an overview, and a list of all the options. Here's my config file:

bare: yes
break-before-br: no
clean: yes
drop-proprietary-attributes: yes
fix-uri: yes
indent-spaces: 4
indent: yes
logical-emphasis: yes
markup: yes
output-xhtml: yes
quiet: yes
quote-marks: yes
replace-color: yes
tab-size: 4
uppercase-tags: no
vertical-space: yes
word-2000: yes
wrap: 0

Save this as tidyrc_html.txt in your ftplugin folder (under vimfiles).

One more file: add the following line to (or create) html.vim, also in ftplugin:

map <leader>tidy :%! tidy -config ~/vimfiles/ftplugin/tidyrc_html.txt <CR>

To use it, just open an HTML file, and type /tidy. (That / is the <leader> key.)

There you go! Not a quick solution, by any means, but now you're a bit better equipped for editing those huge, messed-up HTML files.


I use this script: https://github.com/maksimr/vim-jsbeautify

In the above link you have all the info:

  1. Install
  2. Configure (copy from the first example)
  3. Run :call HtmlBeautify()

Does the job beautifully!


The main problem using the smart indentation is that if the XML (or HTML) sits on one line as it may end up coming back from a curl request then gg=G won't do the trick. Instead I have just experienced a good indentation using tidy directly called from VI:

:!tidy -mi -xml -wrap 0 %

This basically tells VI to call tidy to cleanup an XML file not wrapping the lines to make them fit on the default 68 characters wide lines. I processed a large 29MB XML file and it took 5 or 6 seconds. I guess for an HTML file the command should therefore be:

:!tidy -mi -html -wrap 0 %

As mentioned in comments, tidy is a basic tool which you could find on many base Linux / MacOS systems. Here is the projet's page in case you wish you had it but don't: HTML Tidy.


There's several things that all need to be in place. Just to summarize them all in one location:

Set the following option:

:filetype indent on
:set filetype=html           # abbrev -  :set ft=html
:set smartindent             # abbrev -  :set si

Then either move the cursor to the top of the file and indent to the end: gg =G
Or select the desired text to indent and hit = to indent it.


This is my solution that works nicely for opening "ugly" HTML in a nicely spaced way:

vim fileIn.html -c "set sw=2 | %s/>/>\r/ | execute 'normal gg=G' | set nohlsearch | g/^\\s*\$/d"
  • The sw command is because my default is 4, which is too high for HTML.
  • The next part adds a newline (Vim thinks it's a carriage return, sigh) after each element (>).
  • Then re-indent the entire file with =.
  • Then unhighlight > (since I have set hlsearch in my vimrc).
  • Then remove all empty/whitespace-only lines (see "Vim delete blank lines" for more, also this is double-escaped because it's in the shell).

You can even add | wq! fileOut.html to the end if you don't want to enter Vim at all, but just clean up the file.


You can integrate both tidy and html-beautify automatically by installing the plugin vim-autoformat. After that, you can execute whichever formatter is installed with a single keystroke.


I tried the usual "gg=G" command, which is what I use to fix the indentation of code files. However, it didn't seem to work right on HTML files. It simply removed all the formatting.

If vim's autoformat/indent gg=G seems to be "broken" (such as left indenting every line), most likely the indent plugin is not enabled/loaded. It should really give an error message instead of just doing bad indenting, otherwise users just think the autoformat/indenting feature is awful, when it actually is pretty good.

To check if the indent plugin is enabled/loaded, run :scriptnames. See if .../indent/html.vim is in the list. If not, then that means the plugin is not loaded. In that case, add this line to ~/.vimrc:

filetype plugin indent on

Now if you open the file and run :scriptnames, you should see .../indent/html.vim. Then run gg=G, which should do the correct autoformat/indent now. (Although it won't add newlines, so if all the html code is on a single line, it won't be indented).

Note: if you are running :filetype plugin indent on on the vim command line instead of ~/.vimrc, you must re-open the file :e.

Also, you don't need to worry about autoindent and smartindent settings, they are not relevant for this.


None of the answers worked for me because all my HTML was in a single line.

Basically you need first to break each line with the following command that substitutes >< with the same characters but with a line break in the middle.

:%s/></>\r</g

Then the command

gg=G

will indent the file.


As tylerl explains above, set the following:

:filetype indent on
:set filetype=html
:set smartindent

However, note that in vim 7.4 the HTML tags html, head, body, and some others are not indented by default. This makes sense, as nearly all content in an HTML file falls under those tags. If you really want to, you can get those tags to be indented like so:

:let g:html_indent_inctags = "html,body,head,tbody" 

See "HTML indenting not working in compiled Vim 7.4, any ideas?" and "alternative html indent script" for more information.


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to vim

Why does using from __future__ import print_function breaks Python2-style print? How to run vi on docker container? How can I install MacVim on OS X? Find and replace strings in vim on multiple lines Running Python code in Vim How do I set the default font size in Vim? Move cursor to end of file in vim Set encoding and fileencoding to utf-8 in Vim How to select all and copy in vim? Why I've got no crontab entry on OS X when using vim?

Examples related to vi

How to run vi on docker container? Find and replace strings in vim on multiple lines How can I delete multiple lines in vi? Is there a short cut for going back to the beginning of a file by vi editor? vi/vim editor, copy a block (not usual action) How to go back (ctrl+z) in vi/vim How do I exit the Vim editor? vim line numbers - how to have them on by default? Go to beginning of line without opening new line in VI How to take off line numbers in Vi?

Examples related to indentation

How to indent/format a selection of code in Visual Studio Code with Ctrl + Shift + F Python IndentationError unindent does not match any outer indentation level How to change indentation mode in Atom? How to set HTML Auto Indent format on Sublime Text 3? "Expected an indented block" error? Indent starting from the second line of a paragraph with CSS Indentation Error in Python How to fix/convert space indentation in Sublime Text? How to make the tab character 4 spaces instead of 8 spaces in nano? IndentationError: unexpected unindent WHY?