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

Viewed 116855

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.

12 Answers

With filetype indent on inside my .vimrc, Vim indents HTML files quite nicely.

Simple example with a shiftwidth of 2:

<html>
  <body>
    <p>
    text
    </p>
  </body>
</html>

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.

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.

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.

Tagging onto wisbucky's answer, here were my steps to diagnose and fix the basic use of gg=G for indenting xml:

Detecting that there's a problem:

gg=G
(says 115 lines indented but actually all lines are still at left edge)

:se indentexpr?
indentexpr=

:scriptnames
(look for one ending in /indent/xml.vim but it's not there)
(look in system folder to make sure /usr/share/vim/vim81/indent/xml.vim exists --- it does)

Fixing the problem:

:se ft?
filetype=xml

:filetype
filetype detection:ON  plugin:OFF  indent:OFF

:filetype indent on
:filetype
filetype detection:ON  plugin:OFF  indent:ON

:e
:se indentexpr?
indentexpr=XmlIndentGet(v:lnum, 1)

gg=G

The :se indentexpr? sanity check is from https://stackoverflow.com/a/11660992/115246

Related