Change 2-space indent to 4-space in vim

Vim

Vim Problem Overview


I've some codes copied from the Internet that have 2-space indenting and I want to change it into 4-space indenting. I wonder if there is a short vim routine to accomplish the task without having to write vim script? Here is how I'm currently doing it with an HTML file:

  • Record a macro
  • Go to the beginning of a line
  • Visual select all whitespaces until the first occurrence of "<"
  • Yank and paste all whitespaces (basically to double them)
  • Replay the macro till the end of the file

In short qa0vt<yp<esc>jq

Pitfalls:

The macro fails for a blank line or a line that doesn't start with "<". And I have no idea how to extend this solution to non-HTML file.

Vim Solutions


Solution 1 - Vim

A general way of changing the indent is by changing the tabstop:

Paste your file into an empty buffer, then:

:set ts=2 sts=2 noet
:retab!

This changes every 2 spaces to a TAB character, then:

:set ts=4 sts=4 et
:retab

This changes every TAB to 4 spaces.

The advantage of this method is that you can also use it the other way around, to convert from 4 to 2 spaces for example.

Solution 2 - Vim

It may be possible with :set shiftwidth=4 and gg=G.

Solution 3 - Vim

What I do is very similar to esneider and cforbish's approaches, but a bit quicker to type:

:%s/^\s*/&&

Simply replaces leading space (spaces or tabs) with twice as much leading space (& is substituted with the matched expression).

Solution 4 - Vim

This is a very old question, however all the answers are ... wrong ... Vim has a very easy way to reindent the entire file. I learned this after writing my own function to do it, so I'm in the same ignorance boat ;)

type

gg=G

this is assuming that you have your tabstop set to what you like, (so for the OP it would be ts=4)

I learned this from http://vim.wikia.com/wiki/Fix_indentation , which mentions

> In normal mode, typing gg=G will reindent the entire file. This is a special case; = is an operator. Just like d or y, it will act on any text that you move over with a cursor motion command. In this case, gg positions the cursor on the first line, then =G re-indents from the current cursor position to the end of the buffer.

Solution 5 - Vim

I used this regular expression (it doubles the number of leading spaces):

%s;^\(\s\+\);\=repeat(' ', len(submatch(0))*2);g

Solution 6 - Vim

Similar (but somewhat simpler) to cforbish's answer, this regex will duplicate the leading spaces

:%s/^\( \+\)/\1\1

Or you can use this other regex to transform 2-spaces into 4-spaces, preserving single spaces (and odd amounts in general)

:%s/^\(\(  \)\+\)/\1\1

That is,

  • 1 space ⇢ 1 space
  • 2 spaces ⇢ 4 spaces
  • 3 spaces ⇢ 5 spaces
  • 4 spaces ⇢ 8 spaces

Solution 7 - Vim

In addition to @spro's answer, I put this in my .vimrc

command! -range=% Format :<line1>,<line2>s/^\s*/&&

Just type :Format.

With visual selection, this only formats the selected lines.

Without visual selection, this formats the whole file.

Solution 8 - Vim

This is a variant of the regex based answers.

I have a bash script in my local bin directory that will double the amount of whitespace at the start of a line. Input can be stdin or a file:

$ cat ~/bin/dblsp
#!/bin/bash

file=${1--}

while IFS= read -r line; do
    echo "$line" | sed 's/\s*/&&/'
done < <(cat -- "$file")

I use this within vim by visually selecting a line and issuing the following command:

:'<,'>!dblsp

This saves me the need to type (or remember) the regex.

I also use it in maps like the following:

nnoremap <leader>] `[V`]!dblsp<CR>

which will apply it to a block of recently pasted text. I usually use the following map to paste rather than :set paste

nnoremap <leader>p :r !xclip -o<CR>

My usual workflow is:

  • select code snippet (eg the example code on this page is 2 spaces but I want 4)
  • paste code snippet (,p)
  • change spacing (,])

or simply changing the indent on yanked blocks pasted from another buffer.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLim H.View Question on Stackoverflow
Solution 1 - VimDaan BakkerView Answer on Stackoverflow
Solution 2 - VimperrealView Answer on Stackoverflow
Solution 3 - VimsproView Answer on Stackoverflow
Solution 4 - VimChase VasicView Answer on Stackoverflow
Solution 5 - VimcforbishView Answer on Stackoverflow
Solution 6 - VimesneiderView Answer on Stackoverflow
Solution 7 - VimEliView Answer on Stackoverflow
Solution 8 - VimhtaccessView Answer on Stackoverflow