9

From time to time I have to work with code that isn't indented to the level of indentation I have Vim set up to (4 spaces per level), usually after copy/pasting something in the file. I usually make do with << and >>. The problem is they don't jump to the next indentation level, they just add or subtract 4 spaces.

If I have code like this

if condition:
    do this
   do that

doing >> on do that will result in

if condition:
    do this
       do that

I want it to go to this

if condition:
    do this
    do that

Beside easily matching the indentation of the line above, I want it to jump to the next level of indentation, not add 4 spaces.

This is what I have in my .vimrc regarding indentation

:set tabstop=4 shiftwidth=4 expandtab
Dumitru
  • 780
  • 1
  • 7
  • 10
  • If you also have filetype plugin indent on in your .vimrc, filetype (and plugin) indentation-related rules will apply. I.e. check what your tabstop value actually is (set tabstop? will do; same for the other settings), when editing, and change those values by adding your line to an 'after' file, something like: http://stackoverflow.com/a/159066/5000478 – VanLaser Oct 10 '16 at 13:43
  • 3
    >> and << respectively add and remove indent which is not what you want. What you want is "formatting", which is done with ==. – romainl Oct 10 '16 at 14:01
  • could also map :nnoremap >> ^i<tab><esc> if you really want tab behaviour on >> – Wolfie Oct 10 '16 at 14:07
  • @romainl == will jump to the level of the line above. While a good thing to know, it would not work in all cases I'm interested in. As an addition to the question, what I want is for >> and << to indent/dedent up to the next multiple of shiftwidth from the border in that direction. – Dumitru Oct 10 '16 at 14:51
  • 2
    No, == uses either equalexpr or equalprg to reformat the given lines. – romainl Oct 10 '16 at 19:26
  • @Dumitru I'm not sure, but maybe you could try enabling the 'shiftround' option in your vimrc: set shiftround – user9433424 Oct 10 '16 at 19:39

2 Answers2

12

When you use one of the commands {count}>>, {count}<<, >{motion} or <{motion}, on some lines which have already been indented, and you want their new indentation level to be a multiple of your 'shiftwidth' option value, you can enable the 'shiftround' option, and add this line in your vimrc:

set shiftround
user9433424
  • 6,138
  • 2
  • 21
  • 30
2

If you always want >> to indent to the next tabstop and << to delete to the last tabstop, you can rebind them like so:

:nnoremap << ^i<BS><esc>
:nnoremap >> ^i<tab><esc>

This will move the cursor, but you could probably do some mark trickery to move it back. ^ doesn't leave a m' mark, but you can leave one manually inside the binding.

Wolfie
  • 667
  • 3
  • 8