Wrong indentation when editing Yaml in Vim

Vim does not seem to correctly react at a dash symbol in YAML files therefore breaking the format.

For example I have a block which should look like this:

  handlers:
        - name: restart exim4
          service: name=exim4 state=restarted

When I finish typing restart exim4 and type service: Vim reindents my final service line:

  handlers:
        - name: restart exim4
        service: name=exim4 state=restarted

So clearly Vim tries to align sentences column-wise but that's not what is needed in YAML. I want to create an array with two values.

How to fix that?


Solution 1:

In order to get the nice 2-space YAML as the default when I hit carriage return after the colon, I added this to my .vimrc:

autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab

This also plays nice with the dash for the OP's expected result.

Solution 2:

Install this plugin:

https://github.com/chase/vim-ansible-yaml

It is made with Ansible in mind, but in theory it will work with all kinds of YAML files. You will have to :set filetype=ansible unfortunately, if you are not working with ansible related files.

Solution 3:

You can disable reindent when you type : key:

:set indentkeys-=<:>

Please edit ~/.vimrc file, and add these lines:

filetype plugin indent on
autocmd FileType yaml setl indentkeys-=<:>

Note: autocmd comes after filetype.


You can trigger reindent by typing CTRL-F in INSERT mode, for example:

hello: world
    foo: bar<C-F>

Solution 4:

You can use this autocommand to make Vim properly indent YAML files (put it to your .vimrc):

" Fix auto-indentation for YAML files
augroup yaml_fix
    autocmd!
    autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab indentkeys-=0# indentkeys-=<:>
augroup END

Basically, for YAML file it instructs Vim to:

  • Use 2 spaces for indentation.
  • Use spaces instead of tabs.
  • Skip re-indenting lines after inserting a comment character (#) at the beginning of a line, or a colon.

Solution 5:

You can add a comment in your YAML to tell Vim special config for this file. For example:

# vim: set shiftwidth=2 tabstop=2 softtabstop=-1 expandtab:
foo:
  bar:
  - a
  - b

Then everyone, who use this file with a default vim, can share the file creator's configuration. It works well especially when cooperating.