Vim indent xml file
XmlVimXml Problem Overview
I am learning Vim but I thought this was a simple task but I cannot get it to work. I have browser SO but the solutions are not working for me.
I am trying to correctly indent an file (xml). The command I use is:
gg=G
or ggVG= (made this one up myself probably does something different ;))
My .vimrc is:
syntax on
filetype plugin indent on
set nu
Xml Solutions
Solution 1 - Xml
I like Berei's answer. However, I think the following is a little more flexible in that you don't have to alter your vimrc
file. Plus it is easier to format select portions of the XML file (something I happen to do a lot).
First, highlight the XML you want to format.
Then, in normal mode, type ! xmllint --format -
Your command-line at the bottom will look like this:
:'<,'>!xmllint --format -
Then hit enter.
Technical Explanation
The selected text is sent to the xmllint
command, then --format
'ed, and the results of xmllint
are placed over your selected text in vim. The -
at the end of the command is for receiving standard input - which, in this case, is the selected text that vim sends to xmllint
.
Solution 2 - Xml
Use an external program to indent your xml
files. In this case I've choosen xmllint
, so set the command to the equalprg
option:
:set equalprg=xmllint\ --format\ -
Now you can execute
gg=G
to let xmllint
format your xml
files.
To get it every time you use [tag:vim], use an autocommand
to set it.
autocommand
from a comment below
au FileType xml setlocal equalprg=xmllint\ --format\ --recover\ -\ 2>/dev/null
Solution 3 - Xml
A simple solution that I like which doesn't require any 3rd party tool is to insert a newline before each opening tag '<...>'. Then you can use standard vim auto-indentation. In short:
%s/</\r</g
gg=G
to auto indent
Solution 4 - Xml
Short answer: Turn on matchit.vim. You can add packadd matchit
to your .vimrc
, or use vim-sensible, which enables it by default.
Long answer: I have tried many strategies to auto-indent XML in Vim, including the xmllint approach discussed on the Vim wiki. The problem with xmllint
(and the same approach with other external CLI tools such as xmlformat
and tidy
, too) is that they all insist on squeezing out blank newlines. If all you want is to indent your XML, without removing blank lines, comments and/or other intentional formatting, then xmllint
is not the best choice.
It turns out that Vim's equals (=) command already supports XML, as long as the matchit.vim script is enabled. One super easy way to enable it is to adopt tpope's vim-sensible. Another is to add packadd matchit
to your .vimrc
. Then, XML formatting will "just work" out of the box.
Solution 5 - Xml
This is easy to achieve once ~/.vimrc is setup properly.
Set the following options in ~/.vimrc:
filetype indent on
set smartindent
This allows you to move the cursor to the top of the file and indent to the end: gg=G
You can also select the desired text with visual mode and hit = to indent it.
Solution 6 - Xml
Jesse Hogan's answer is good, but I'd rather more simple answer:
While you are in vim and your XML file is opened, in normal mode write this:
:%!xmllint --format %
then press Enter. All of your XML file will be formatted.
remember you should have installed xmllint before.
Solution 7 - Xml
In VIM, I auto-indent the whole file (using hard tabs) using the following command:
:%!XMLLINT_INDENT="^I" xmllint --format -
The ^I
is a single character you generate via: CTRL+v,CTRL+i
Solution 8 - Xml
I had the same problem. It turned out, that the line
set viewdir=~\.vim\views\
in my .vimrc
caused the problem. Just make sure, you don't have it.
Solution 9 - Xml
for those one which is using coc.nvim
plugin, you can install coc-xml
by :CocInstall coc-xml
, then mapping format key in your config file: nmap <silent> fm <Plug>(coc-format)
. From now on, you can format not only xml file but other file very easy
Solution 10 - Xml
Cannot get coc-xml
working due to some java issue. Turns out using python's xml module could be a quick solution given many modern systems already come with python. Add below to your .vimrc
> com! FormatXML :%!python3 -c "import xml.dom.minidom, sys; print(xml.dom.minidom.parse(sys.stdin).toprettyxml())"
Now you can do :FormatXML
from command mode. Then set syntax highlight with
:set ft=xml
# OR
:set syntax=xml
Bonus: since I was doing this with SAML you can quickly decode base64 inside vim/neovim by selecting the base64 text(visual mode) and do !base64 -d
in command mode. it will show as below in command:
> :'<,'>!base64 -d