I have key mapping in my ~/.vimrc file that re-indents edited source code on the fly. It looks like as follows:

" press F4 to fix indentation in whole file; overwrites marker 'q' position
noremap <F4> mqggVG=`qzz
inoremap <F4> <Esc>mqggVG=`qzza

Short explanation:

mq      place marker 'q' at cursor position
ggVG    select all text
=       re-indnet text
`q      return cursor back to position stored in 'q' marker
zz      center the display over the cursor
a       return to insert mode if called from it

It basically works, but has two shortcomings.

The first one is that it overwrites the q marker. I used this marker to store cursor position. I choose q because it is very unlikely that I would use this letter as a marker. Despite this, is there any more clever approach to achieve this, without destroying q marker?

The second one occurs in the insert mode, when the cursor is on the beginning of a line. In such condition, F4 re-indents as expected, but also moves cursor one position right. I tried to fix it by using <C-o> instead of <Esc>, but it looks like <C-o> is applicable only to editor :commands, not to move commands. How can I fix it?


You can use the last jump mark (m') as a temporary mark. To avoid using a different command to re-enter insert mode (i vs. a), you can use the gi command, which re-enters insert mode at the position where it was last exited:

inoremap <F4> <Esc>m'ggVG=``zzgi

You can use i instead of a to keep the cursor at old position:

inoremap <F4> <Esc>mqggVG=`qzzi

I think you can't do better with q marker, from vim wiki:


You can not use a marker without destroying it.


A little bit shorter:

inoremap <F4> <Esc>m'gg=G''zzgi

We no need to use visual mode to make indent corrections. Instead use visual mode to select and then re-indent (VG=) we can use re-indent with direction (=G).

  • You should explain your answer a little, e.g. how it is more clever and how it does not destroy the q marker ... Sep 18 '14 at 9:53

Your Answer
