Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell Vim to auto-indent before saving

I have recently started using Vim for my graduate level projects. The main problem I face is that sometimes I check in unindented code. I feel if I can somehow create a shortcut of auto-indent+save+close then that should solve my problem.

My .vimrc file:

set expandtab
set tabstop=2
set shiftwidth=2
set softtabstop=2
set pastetoggle=<F2>
syntax on
filetype indent plugin on

Is there any way to create such command shortcuts & override with :x (save+exit).

Please let me know.

like image 202
Amey Jah Avatar asked Apr 13 '13 19:04

Amey Jah


3 Answers

I would recommend turning on autoindent to avoid this problem in the first place. It is much easier to work with properly indented code at every stage of development.

set autoindent

Read the docs via :help autoindent.

However, the = command will indent lines according to the filetype's rules. You can create a BufWritePre autocmd to perform indentation on the whole file.

I've not tested this, and don't know how well it will actually work:

autocmd BufWritePre * :normal gg=G

Read :help autocmd for more information on the topic. gg=g breaks down as:

  • :normal execute as a normal mode editing command rather than an :ex command
  • gg move to the top of the file
  • = indent until...
  • G ... the end of the file.

I really don't recommend this strategy though. Get used to using set autoindent instead. It's probably unwise to define this autocmd on all files (as with *). It could be done on certain filetypes only:

" Only for c++ files, for example
autocmd BufWritePre *.cpp :normal gg=G
like image 137
Michael Berkowski Avatar answered Sep 30 '22 06:09

Michael Berkowski


Add the following to your .vimrc:

" Restore cursor position, window position, and last search after running a
" command.
function! Preserve(command)
  " Save the last search.
  let search = @/

  " Save the current cursor position.
  let cursor_position = getpos('.')

  " Save the current window position.
  normal! H
  let window_position = getpos('.')
  call setpos('.', cursor_position)

  " Execute the command.
  execute a:command

  " Restore the last search.
  let @/ = search

  " Restore the previous window position.
  call setpos('.', window_position)
  normal! zt

  " Restore the previous cursor position.
  call setpos('.', cursor_position)
endfunction

" Re-indent the whole buffer.
function! Indent()
  call Preserve('normal gg=G')
endfunction

If you want all file types to be auto-indented on save, which I strongly recommend against, add this hook to your .vimrc:

" Indent on save hook
autocmd BufWritePre <buffer> call Indent()

If you want only certain file types to be auto-indented on save, which I recommend, then follow the instructions. Lets say you want C++ files to be auto-indented on save, then create ~/.vim/after/ftplugin/cpp.vim and put this hook there:

" Indent on save hook
autocmd BufWritePre <buffer> call Indent()

The same would go for any other file types, i.e. ~/.vim/after/ftplugin/java.vim for Java and so on.

like image 44
Alexander Shukaev Avatar answered Sep 30 '22 05:09

Alexander Shukaev


To indent a file that already exists, you can use the shortcut gg=G (not a command; just press g twice, then =, then Shift+g), particularly since you are using the filetype indent ... line.

Vim: gg=G aligns left, does not auto-indent

like image 20
maditya Avatar answered Sep 30 '22 07:09

maditya