23

I'm editing a Python file that uses two spaces for programmatic indents - I prefer 4 spaces. In my .vimrc I have the following settings related to indentation:

set tabstop=4                     "Indentation levels every four columns
set expandtab                     "Convert all tabs typed to spaces
set shiftwidth=4                  "Indent/outdent by four columns
set softtabstop=4

How do I get Vim to convert all the existing 2 space indents to be 4 space indents?

In other words:

if something:
  dothis()

becomes

if something:
    dothis()

When I tried gg=G

def check():
  for a in list:
    for  b in list2:
      check(a, b)
      while (len > MAX) :
        poll()

  while(len(thelist) > 0) :
    poll()  

  return results

became

def check():
    for a in list:
    for  b in list2:
    check(a, b)
    while (len > MAX) : 
        poll()

        while(len(thelist) > 0) :
            poll()

            return results
CSchulz
  • 10,882
  • 11
  • 60
  • 114
half full
  • 2,725
  • 3
  • 17
  • 8

7 Answers7

49

In order to double the number of spaces at the beginning of every line (and only at the beginning):

:%s/^\s*/&&/g

& in replacement pattern is the matched pattern.

Probably it will not have any side-effect for you.

Benoit
  • 76,634
  • 23
  • 210
  • 236
  • 2
    Thank you! I have been looking for this my whole life (well, maybe just the past 5 years or so)! – chown Nov 20 '11 at 20:29
  • For all those who love two-space tabs, fight back with [`:%s/^\(\s*\)\1/\1/`](https://stackoverflow.com/a/9124761/837710) to undo! – Casey Jones Mar 13 '21 at 02:12
18

Pressing gg=G is the command to re-indent everything in a file. If you have other elements that can be re-indented, vim will indent these as well, which doesn't always give the desired effects. You'll have to clean these up manually if they're ugly.

Alternately, you can use the > command to indent, with ranges to go through the file somewhat efficiently manually. 99>k, for example, would indent the 99 lines below the cursor by one level.

Ezra
  • 7,552
  • 1
  • 24
  • 28
  • I must be do something wrong - this doesn't work for me. It seems to make all lines below an indent indented to that indent so everything gets pushed over. Probably not describing that very well. – half full Mar 07 '11 at 08:44
  • Which part? If it's the `>` part, you can use `<` to unindent. You have to use discretion, and an appropriate number. 99 won't work all the time. If it's the first part, make sure the filetype is set. Try `:set filetype=python` and then `gg=G` again. – Ezra Mar 07 '11 at 08:48
  • I did :set filetype=python and the gg=G again, but got the same. I've updated the question to show this. – half full Mar 07 '11 at 08:57
  • I wouldn't trust the `=` command with python. Actually I expect `=` to indent languages where indentation is just cosmetic. In Python it is not and indenting a line in a different way has a different meaning. – Benoit Mar 07 '11 at 09:04
  • Hmm... works for me. Without going too far down the rabbit-hole, and figuring out what's /really/ going on, I'm just going to suggest using [reindent.py][http://svn.python.org/projects/python/trunk/Tools/scripts/reindent.py]. It's annoying that you have to leave vim, but at least it'll be done. – Ezra Mar 07 '11 at 09:09
  • My experience is that this works really badly with indentation sensitive languages like Python. – lindhe Aug 07 '20 at 14:38
4

I've found the reindent script http://pypi.python.org/pypi/Reindent/0.1.0 works well for me. Not pure vim, but really easy!

After its installed you can use it in vim with

:%! reindent

(ie pipe the entire buffer through the reindent program) and it's done.

From the command line it can be used to reindent multiple files (eg all files in a directory, or even recursively down a directory tree).

Chris Crook
  • 243
  • 3
  • 7
4

The best current way to reformat Python, fix many other issues, and also make it PEP8 compliant is to use autopep8. See this related question. So after you've installed autopep8 (e.g. pip install autopep8) in vim you do:

:%! autopep8 -

There's also a vim-autopep8 plugin to make things even simpler.

Community
  • 1
  • 1
Pierz
  • 7,064
  • 52
  • 59
2

try the following substitution command:

:%s/  /    /g

(To clarify: there are two spaces between the first and second '/' and four the second and third '/'.)

One helpful command when working with whitespace issues is also the set list command which will visually show all whitespace. Use set nolist to unset.

Paul
  • 7,836
  • 2
  • 41
  • 48
  • Sorry, forgot the `%` in the first version, that is important, else the substitution only happens on the first line. – Paul Mar 07 '11 at 07:45
  • 4
    Won't this affect other things besides my programmatic indents? – half full Mar 07 '11 at 07:45
  • Yes it would - if you have many double spaces in your code (apart from indentation) that would be a problem. I didn't find this to be a big problem and it's a no-brainer to remember. – Paul Mar 07 '11 at 07:54
  • 1
    This substitution command will double indentation while only affecting spaces before the first non-space character: `:%s/\v^(( )+)/\1\1/` (Edit: There's two spaces between the inner parentheses, but Markdown is eating one) – TerrorBite Jun 25 '11 at 13:51
0

The vim plugin vim-autoformat integrates the formatter autopep8 into vim automatically, if it is installed. You can format the whole file, or the visually selected part using a single keystroke.

More importantly, vim-autoformat takes the relevant settings of your .vimrc into account, e.g. if you have

set shiftwidth=4

in your .vimrc, it will pass this information on to autopep8.

chtenb
  • 14,924
  • 14
  • 78
  • 116
-1

Have you tried?

:retab

I'm not in front of a machine with Vim at the moment so I can't verify this.

Greg Sexton
  • 9,189
  • 7
  • 31
  • 37
  • 2
    The `:retab!` command is ideal if you want to switch from soft tabs (using spaces) to hard tabs (using the tab character) or vice versa. In this case, the OP is trying to switch from 2 spaces to 4 spaces for indentation, so `:retab!` is not the best tool for the job. – nelstrom Mar 07 '11 at 12:46