将 vim 中的2-空间缩进更改为4-空间

我有一些代码从互联网上复制,有2个空间缩进,我想把它变成4个空间缩进。我想知道是否有一个简短的 vim 例程来完成任务而不必编写 vim 脚本?下面是我目前使用 HTML 文件的方法:

  • 记录一个宏
  • 转到一行的开头
  • 可视化选择所有空格,直到第一次出现“ <”为止
  • 拖拽并粘贴所有的空格(基本上是将它们加倍)
  • 重播宏,直到文件结束

简而言之就是 qa0vt<yp<esc>jq

陷阱:

对于空行或不以“ <”开头的行,宏将失败。我不知道如何将这个解决方案扩展到非 HTML 文件。

42462 次浏览

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

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

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

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.

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

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).

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.

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.

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.