Okay, let me first explain, what is happening here.
When indenting lines, Vim will indent the line, which means depending on the 'shiftwidth', 'tabstop', 'expandtab' and possibly also the 'vartabstop' options determine whether to insert leading tabs or blanks into the line. When the 'startofline' option is at its default value, the cursor will be moved to the first non-blank on the line.
The interesting thing is what happens, if the 'startofline' option is switched off. Well, basically the cursor stays at the exact same position, as it was before something was inserted. But since shifted right, the cursor appears to move. Now remember, that depending on a bunch of options, several blanks might actually be replaced by a single tab, so that technically the byte column might even decrease(!), while the line still appears to be shifted to the right.
You can verify this, by comparing the output of
:echo virtcol('.') before and after you have (de-)indented your line.
So according to the documentation, the line will always be shifted by the amount of
shiftwidth() spaces. So you need to adjust the cursor position (but not the byte column). This can be done like this:
let vcol = virtcol('.')
exe "norm!". (vcol + shiftwidth()) . '|'
exe "norm!". (vcol - shiftwidth()) . '|'
nnoremap >> :call Indent(1)<cr>
nnoremap << :call Indent(0)<cr>
This will map the
>> in normal mode to perform the normal
>> comamnds and will afterwards re-adjust the cursor positioning.
Error management, range handling and handling e.g. visual mode has been intentionally left out. Those cases should probably be handled if a plugin is made out of it.