如何在vim中插入细微差别的重复文本?


11

我想插入这样的文本:

similar text wordA similar text ...
similar text wordB similar text ...
similar text wordC similar text ...

我知道我可以多次粘贴文本,然后使用替换为每行更改单个单词,但是我仍然发现此方法非常不便。

有没有一种方法可以将单词或单词列表保存到“变量”中,然后使用此变量生成相似的文本?


编辑我在原始问题中做了一些不清楚的事情,实际上,我正在尝试进行一些非常相似的函数定义,因此wordA wordB...在每个文本克隆中可能会出现很多次,并且文本可能包含很多行。模式完全是这样的:

similar_text1 wordA similar_text2 wordA similar_text3 ...
similar_text1 wordB similar_text2 wordB similar_text3 ...
similar_text1 wordC similar_text2 wordC similar_text3 ...

(文本可能包含换行,并且wordA,wordB ...可能存在多次)


第二次编辑 每次我做这样的工作时,“ similar_text”部分可能会有所不同,因此该工作的解决方案最好是可重用的。因为我试图做出非常相似的函数定义,或者将字符串映射到函数映射表。

阅读答案和实践后,我发现将这项工作视为某种替代更为方便,因为可能包含换行符的单独“ part1”,“ part2” ...“ partN”很难编写,因此请写首先是模板:

similar_text1 $WORD similar_text2 $WORD similar_text3 ...
(text may contain <ENTER>, make sure $WORD not exist in "similar_text" parts )

然后尝试放置文本的克隆,但用单词列表替换$ WORD更直觉。

因此,似乎我的问题变成了“如何多次克隆文本块,但是每次都用列表中的单词替换其中的关键字?”


这就是为什么要使用寄存器的原因。您可以将文本拉动(复制)到寄存器,然后使用该寄存器。宏可用于执行类似以及重复的任务。
SibiCoder '16

Answers:


7

您可以使用以下功能:

function! GenerateLines()
    let firstpart="similar text part 1"
    let secondpart="similar text part 2"

    let words=["wordA","wordB","wordC","wordD","wordE"]

    for word in words
        let line = firstpart . word . secondpart
        call append(line('.')+1, line)
        normal j
    endfor
endfunction

在变量中firstpartsecondpart将要重复的文本放在单词前后,在列表中,words将要更改的单词重复。

然后循环将为列表的每个单词创建行的内容,将行插入缓冲区,然后转到新行。

然后,您可以简单地调用函数:call GenerateLines()


编辑为了使操作更容易,您还可以将不同的部分作为参数传递,该函数应如下所示:

function! GenerateLines(firstpart, secondpart, words)
    for word in a:words
        call append(line('.')+1, a:firstpart . word . a:secondpart)
        normal j
    endfor
endfunction

您可以这样称呼它:

call GenerateLines("first part", "second part", ["wordA","wordB","wordC","wordD","wordE"])

您可以使用call map(a:words, 'a:firstpart . v:val . a:secondpart')和避免循环call append(line('.'), a:words)
安东尼

由于我经常使用很长的“第一部分”和“第二部分”,甚至“第三部分”进行此类编辑,并且这些部分可能包含换行符,因此在命令模式下键入太多内容似乎太长了,所以也许更方便将文本拖到寄存器中,然后使用函数从寄存器生成文本?
social_loser '16

我编辑了问题,它改变了很多,不便之处,敬请原谅。
social_loser

5

在这种情况下,我的策略会有所不同,但通常遵循以下步骤:

  1. 写出唯一的单词,例如

    wordA
    wordB
    ...
    wordK
    
  2. 要么

    a)搜索并替换,例如

    :%s/\w\+/similar text \0 similar text .../
    

    b)或使用可视块模式,请参见:h blockwise-visual。特别是,我将选择单词并用于I在前面插入相似的文本,或在后面A附加相似的文本。

我认为当您相对很少执行这种编辑任务时,这种策略是有意义的。但是,如果发现需要经常执行此操作,则应遵循@statox的建议,并使用扩展单词列表的功能。


我认为解决方案取决于单词列表的来源。如果是来自文件,那么:read接下来的替换很有意义。
安东尼

您的解决方案很容易实现,并且可以轻松解决我在原始问题中提出的问题。但是,我的原始帖子中存在一些错误,我进行了2次编辑,并且更改了很多,谢谢您的回答,对我的更改和英语不佳表示抱歉:)
social_loser

@social_loser,您可以使用“ \ r”来表示此替换的替换部分,以适应此解决方案
frangio 2016年

2

我认为这是视觉块(Ctrl+ v)的工作。首先,我要写所有不同的词:

wordA
wordB
wordC
wordD
wordE

从第一个光标开始,w然后执行:

<c-v>5j$yA <esc>pA <esc>p

我可以通过按任意多次来控制所需的列数A <esc>p。假设我需要三列,就像上面的命令所示。现在我们有了这个:

wordA wordA wordA
wordB wordB wordB
wordC wordC wordC
wordD wordD wordD
wordE wordE wordE

光标位于wordA第一行中第三行的开头。接下来,我将阻止选择列之间的空白列,这些列向后移动并在之间添加文本。从当前光标位置:

h<c-v>5jI similar text 3<esc>

结果为(%标记光标位置):

wordA wordA%similar text 3 wordA
wordB wordB similar text 3 wordB
wordC wordC similar text 3 wordC
wordD wordD similar text 3 wordD
wordE wordE similar text 3 wordE

对下一列重复:

bh<c-v>5jI similar text 2<esc>

以及最后/第一个(左侧的)列:

b<c-v>5jIsimilar text 1 <esc>

最终导致:

similar text 1 wordA similar text 2 wordA similar text 3 wordA
similar text 1 wordB similar text 2 wordB similar text 3 wordB
similar text 1 wordC similar text 2 wordC similar text 3 wordC
similar text 1 wordD similar text 2 wordD similar text 3 wordD
similar text 1 wordE similar text 2 wordE similar text 3 wordE

更新:添加了截屏

在此处输入图片说明


这似乎需要很多输入,但实际上很容易习惯。它使您可以自由更改单词数,列数,甚至列之间的间距。

缺点是您需要知道所使用的不同单词的数量。我5在上面的所有命令中都进行了硬编码,因为它是命令所处理的行数。

调试说明:所有命令均以正常模式开始和结束,如果在命令末尾处于可视模式或插入模式,则说明您做错了什么。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.