自动缩进在vim字符串替换新行?

时间:2010-04-28 19:42:41

标签: regex vim

我正在使用以下命令自动替换某些代码(在现有段之后添加新代码段)

%s/my_pattern/\0, \r some_other_text_i_want_to_insert/

问题在于\rsome_other_text_i_want_to_insert会在新行后插入:

mycode(
  some_random_text my_pattern
)

会变成

mycode(
   some_random_text my_pattern
some_other_text_i_want_to_insert   <--- this line is NOT indented
)

而不是

mycode(
   some_random_text my_pattern
   some_other_text_i_want_to_insert  <--- this line is now indented
)

即。新插入的行不缩进。

我可以用vim或技巧来缩进新插入的行吗?

感谢。

6 个答案:

答案 0 :(得分:4)

试试这个:

:let @x="some_other_text_i_want_to_insert\n"
:g/my_pattern/normal "x]p

这是一步一步:

首先,将要插入的文本放在注册表中......

:let @x="some_other_text_i_want_to_insert\n"

(注意字符串末尾的换行符 - 这很重要。)

接下来,使用:global命令将文本放在每个匹配行之后......

:g/my_pattern/normal "x]p

]p普通模式命令的工作方式与常规p命令相同(即,它将寄存器的内容放在当前行之后),但也会调整缩进以匹配。 / p>

更多信息:

:help ]p
:help :global
:help :normal

答案 1 :(得分:1)

%s/my_pattern/\=submatch(0).", \n".matchstr(getline('.'), '^\s*').'some_other_text'/g

请注意,您必须使用子匹配和连接,而不是&\N。这个答案是基于这样一个事实,即substitute命令将光标放在它进行替换的行上。

答案 2 :(得分:0)

实现相同目标的一种循环方式:您可以记录一个查找下一个my_pattern出现的宏,并在其后插入换行符和替换字符串。如果启用了自动缩进,则无论发现my_pattern的出现位置,都将保持缩进级别。

像这个关键序列:

q 1                  # begin recording
/my_pattern/e        # find my_pattern, set cursor to end of match
a                    # append
\nsome_other_text... # the text to append
<esc>                # exit insert mode
q                    # stop recording

@1

重复

答案 3 :(得分:0)

您可以分两步完成。这类似于Bill的答案,但更简单,更灵活,因为您可以在替换中使用原始字符串的一部分。 首先替换然后缩进。

:%s/my_pattern/\0, \r some_other_text_i_want_to_insert/

:%g/some_other_text_i_want_to_insert/normal ==

如果您将原始字符串的一部分与\0\1等一起使用,只需使用替换字符串的公共部分作为:global(第二个)命令。

答案 4 :(得分:0)

normal =``怎么样?

:%s/my_pattern/\0, \r some_other_text_i_want_to_insert/ | normal =``

<equal><backtick><backtick>:在最近的跳转之前重新索引位置

(抱歉奇怪的格式化,逃避反引用在这里很难使用)

要将它们作为单独的命令保存,您可以执行以下映射之一:

" Equalize and move cursor to end of change - more intuitive for me"
nnoremap =. :normal! =````<CR>

" Equalize and keeps cursor at beginning of change"
nnoremap =. :keepjumps normal! =``<CR>

我将映射读作&#34;均衡最后一次更改&#34;因为dot已经意味着&#34;重复最后一次更改&#34;。

或完全跳过映射,因为=``只有3个键,其中2个是重复。容易腻,柠檬挤压!

<强>参考

:help =
:help mark-motions

答案 5 :(得分:0)

我通过在模式的开头使用\s*来捕获前面的空白来实现这一点。

我正在使用VSCode的vim插件,它似乎与标准vim并不完全匹配,但是对我来说,

:%s/(\s*)(existing line)/$1$2\n$1added line/g

打开

mycode{
    existing line
}

进入

mycode{
    existing line
    added line
}

搜索模式中的括号定义了$1$2所引用的组。在这种情况下,$1(\s*)捕获的空白。我不是vim或regex的不同实现的专家,但是据我所知,这种引用regex组的方式特定于VSCode(或者至少不是通用的)。该here的更多说明。不过,使用\s*来捕获一组空白应该是通用的,或者至少在您的环境中具有相似之处。