在Vim中复制行并附加几个字母

时间:2013-03-21 20:01:34

标签: vim macros text-editor vi

我正在编辑文本文件中的字典,其中包含俄语单词 - 每行一个单词。

有些名词缺少它们的衍生词,这些词汇通常是由少数几个字母附加的同一个词 - 在6-7个变体中,如此屏幕截图所示:

enter image description here

在Vim中我想将光标放在第一列并逐行向下滚动。当我识别出一个名词时,我想按下一些(尽可能少的!)击键来取出那个单词,将它复制在不同的行中并附加字母。

我可以稍后发布%sort u来删除重复项。

如果我可以在整个文件上运行该命令,那将是:

%s/\(.\+\)$/\1^M\1а^M\1ам^M\1ами^M\1ах^M\1е^M\1ном^M/

请您知道如何在Vim中创建这样的“宏”?

4 个答案:

答案 0 :(得分:5)

有几种方法可以解决这个问题。您可以创建宏,也可以创建地图。可以在运行VIM时完成。可以将其中任何一个放在另一个文件中(例如,您的.vimrc或具有特定于此项目的绑定的文件)并在需要时提供。

我还会给你一些关于正则表达式的建议:如果你正在写一些特别复杂的东西,你可以通过\启动正则表达式来大大减少所需\v的数量(即,:s/\v([0-9a-f]+\s)/0x\1/g)。

在VIM中创建宏

您可以在普通模式下按 q ,然后按照要用于宏的键,在VIM中启动宏。然后,您可以通过按 @ 然后按宏的字母来调用宏。在正常模式下再次按 q 可停止录制。

因此,您可以按如下方式输入此宏(使用q寄存器):

q q s/\(.\+\)$/\1\r\1а\r\1ам\r\1ами\r\1ах\r\1е\r\1ном\r/ 输入 q

然后,当您在一条线上并且想要运行此命令时,请从正常模式输入 @ q

将宏存储在文件中并获取文件

在最后一步中创建宏时,您实际在做的是设置q寄存器。您可以通过在命令模式下输入registers来检查这一点。您可以在.vimrc文件中设置此宏,如下所示,每次启动VIM时都可以使用它。

  1. 在(:new)中创建要存储此宏的文件。
  2. 将以下行添加到文件中:

    let @q=":s/\\(.\\+\\)$/\\1\\r\\1a\\r\\1b\\r\\1ам\\r\\1ами\\r\\1ах\\r\\1е\\r\\1ном\\r/^M"

    (如果你猛拉线并用 Ctrl + R 将其粘贴到VIM中,那么在结尾处会有一个正确的^M字符。您需要进行一些手动编辑以确保它在引号内。或者,您可以输入 Ctrl + V Ctrl + M 进入^ M字符。)

  3. 保存文件(:w testmacro.vim)。
  4. 来源(:so %:source %)。
  5. 在您要执行此操作的其中一行上输入 @ q 来测试您的宏。
  6. 稍后,您可以通过运行:so testmacro.vim

    来加载此宏

    创建地图

    您可以改为创建映射。以下映射复制给定行中的最后一个单词,将其粘贴到以下六行,然后附加到每个给定行。

    nnoremap <c-j> yy6pAа<esc>jAам<esc>jAами<esc>jAах<esc>jAе<esc>jAном<esc>j

    “nnoremap”开头的

    n表示它仅在普通模式下运行 noremap表示此命令不会参与任何递归重映射(而使用nmap时,可能会发生这种情况)。 <c-j>映射到 Ctrl + J yy6p猛拉线并将其粘贴6次。 Aa<esc>j附加到当前行的末尾,输入文本(在本例中为a),退出插入模式,然后向下移动一行。

    您可以在VIM的命令模式下输入此命令,也可以将其存储在文件中并使用:source命令加载它。

    将寄存器与映射相结合

    您可以访问映射中的寄存器。这意味着如果您知道输入给定的替换正则表达式将执行您想要的操作,则可以将其保存在寄存器中,然后在当前行上输入命令。

    要执行此操作,请在文件中输入以下命令,然后将其获取:

    nnoremap <c-i> :<c-r>f<cr>
    let @f="s/\\(.\\+\\)$/\\1\\r\\1a\\r\\1b\\r\\1ам\\r\\1ами\\r\\1ах\\r\\1е\\r\\1ном\\r/^M"
    

    现在你可以输入 Ctrl + I 来在当前行的寄存器f中运行替换正则表达式。

    或者,将一些寄存器用于此目的 - 让我们说a-f。

    nnoremap <c-l> yy6p$"apj"bpj"cpj"dpj"epj"fpj
    let @a="a"
    let @b="ам"
    let @c="ами"
    let @d="ax"
    let @e="e"
    let @f="ном
    

    在这种情况下,我们使用能够在点击使用它的命令之前按和寄存器的名称,例如粘贴。

答案 1 :(得分:4)

您可以在q模式下按escape来录制宏。例如,

  1. 将光标放在要编辑的名词上。
  2. qa开始录制宏并将其存储在寄存器a中(其他字母和数字也可用于寄存器)。
  3. 执行您想要执行的任何常规操作(复制行,粘贴,附加字母等,就像您尝试在搜索字符串中显示一样)。
  4. 完成更改后,在escape模式下再次按q
  5. 您的宏现在已在注册a中创建。每当您想重复键序列时,只需按@a

    请注意,您可以在recording模式下执行任何操作,包括任何类型的命令,插入,光标移动等。有关宏和相关选项的更多信息,请查看Vim帮助:h complex-repeat

    Vim寄存器作为占位符共享,用于宏和抽取测试;此功能允许您甚至在文件中保存和编辑宏。有关详细信息,请参阅this question

答案 2 :(得分:1)

这是一个地图解决方案 - 将行复制到缓冲区中,然后使用p进行粘贴。  A附加在行的末尾

  map <F2> 0dwpo<esc>pAa<enter><esc>pAam<enter><esc>pAax ...etc

答案 3 :(得分:1)

如果你的目标是,当你把光标放在一个特殊的单词上并按下某个东西时,vim会附加不同的“后缀”(我希望我使用了正确的单词,但你知道我的意思)。你可以去宏(q)。但是,由于您已经编写了:s命令,因此您可以使用该命令创建映射,并且它会更短。

在命令行中,您可以按<c-r><c-w>获取光标下的单词。所以你可以尝试:

nnoremap <leader>z :s/<c-r><c-w>/& & &..../<cr>

我没有写& & &...部分,因为我不知道(从未尝试过,我在windows下没有vim。我甚至没有窗口)如果换行{{1可以在windows下使用。 \n表示整个匹配的部分,在本例中是光标下的单词。

所以你只需将光标移动到单词,输入&,vim将为你完成工作。 (如果替换部分是正确的:))。