如何重新格式化源文件从2个空格缩进到3?

ste*_*nmm 8 vim perl indentation

这个问题几乎与这个问题完全相同,只是我必须去三个空间(公司编码指南)而不是四个,并且公认的解决方案只会使匹配模式加倍.这是我的第一次尝试:

:%s/^\(\s\s\)\+/\1 /gc 
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为四个空格被三个替换.所以我认为我需要的是一些方法来计算模式匹配"+"的次数,并使用该数字来创建替换的另一面但我觉得这个功能可能在Vim的正则表达式中不可用(让如果你认为可能的话,我知道.

我也尝试通过首先替换最大的缩进然后下一个较小的缩进手动进行替换,直到我将它全部转换为但是这很难跟踪空格:

:%s/^              \(\S\)/                     \1/gc
Run Code Online (Sandbox Code Playgroud)

我可以通过Perl发送它,因为看起来Perl可能有能力使用它的扩展模式.但我无法使用我的Perl版本.这是我试图计算一个的尝试:

:%!perl -pe 'm<(?{ $cnt = 0 })(a(?{ local $cnt = $cnt + 1; }))*aaaa(?{ $res = $cnt })>x; print $res'
Run Code Online (Sandbox Code Playgroud)

我的最后一招是编写一个Perl脚本来进行转换,但我希望在Vim中有一个更通用的解决方案,以便我可以重用这个想法来解决未来的其他问题.

Ama*_*dan 8

让vim为你做吗?

:set sw=3<CR>
gg=G
Run Code Online (Sandbox Code Playgroud)

第一个命令设置shiftwidth选项,即缩进量.第二行说:转到文件顶部(gg)和reindent(=)直到文件末尾(G).

当然,这取决于vim是否具有适合您正在使用的语言的格式化程序.如果没有,可能会搞砸一些东西.

Regexp方式...更安全,但不太可理解:

:%s#^\(\s\s\)\+#\=repeat(' ',strlen(submatch(0))*3/2)#g
Run Code Online (Sandbox Code Playgroud)

(我不得不做一些实验.)

两点:

  • 如果替换开头\=,则将其评估为表达式.
  • 您可以使用许多东西代替/,因此/可用于分割.

  • `:help sub-replace-expression` (2认同)