【问题标题】:Vim multiline editing like in sublimetext?像 sublimetext 中的 Vim 多行编辑?
【发布时间】:2012-07-31 20:01:29
【问题描述】:

我开始使用 gvim,但我不太明白 gvim 中的多行编辑是如何工作的。

例如:

原文:

asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

ctrl+q, jjjjjj , $ 一切都被选中,然后我按 I 进行多行插入。

我的意图是在第一行中插入引号,然后按 Esc:

asd "asd asd" asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;
asd asd asd asd asd;

发生了什么?我期望一种类似于 sublimetext 的行为:

如果您不知道它是如何工作的,它只会重复每一行的操作。怎样才能做到这一点? vim 在这里做什么?

【问题讨论】:

  • 只需录制一个键盘宏来更改第一行,然后播放所有其他行的宏。

标签: vim sublimetext text-editor


【解决方案1】:

放弃 Windows 兼容层,帮自己一个忙。

进入可视块模式的正常快捷方式是<C-v>

其他人处理过录制宏,这里有一些其他的想法:

仅使用 visual-block 模式。

  1. 将光标放在第二个单词上:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. 点击 <C-v> 进入 visual-block 模式并将您的选择扩展到底部:

    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    asd [a]sd asd asd asd;
    
  3. 点击I"<Esc>获取:

    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  4. 将光标放在第三个单词的最后一个字符上:

    asd "asd as|d| asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    asd "asd asd asd asd;
    
  5. 点击 <C-v> 进入 visual-block 模式并将您的选择扩展到底部:

    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    asd "asd as[d] asd asd;
    
  6. 点击A"<Esc>获取:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

使用 visual-block 模式和Surround.vim

  1. 将光标放在第二个单词上:

    asd |a|sd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    asd asd asd asd asd;
    
  2. 点击<C-v> 进入visual-block 模式并将您的选择向底部和右侧扩展:

    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    asd [asd asd] asd asd;
    
  3. 点击S" 用“:”包围您的选择

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    

带有 visual-line 模式和:normal

  1. 点击V 选择整行并将其向底部展开:

    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    [asd asd asd asd asd;]
    
  2. 执行这条命令::'<,'>norm ^wi"<C-v><Esc>eea"<CR>获取:

    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    asd "asd asd" asd asd;
    
    • :norm[al] 允许您在一系列行上执行正常 模式命令('<,'> 部分由 Vim 自动添加,意思是“作用于选定区域”)

    • ^ 将光标放在该行的第一个字符上

    • w 移动到下一个单词

    • i" 在光标前插入"

    • <C-v><Esc> 是 Vim 在此上下文中输入控制字符的方式,这里是 <Esc> 用于退出 insert 模式

    • ee 移动到下一个单词的末尾

    • a" 在光标后追加"

    • <CR>执行命令

    使用Surround.vim,上面的命令变成

    :'<,'>norm ^wvees"<CR>
    

【讨论】:

  • 对于第 4 步和第 5 步,我建议您点击gv 以恢复您之前的视觉选择,然后然后 水平移动,也许使用2e。 (行数越多,gv 越有价值!)
  • surround.vim 在普通模式下使用一个小的s,而在可视模式下使用一个大的S,所以在surround.vim方法的第3步中,击键应该是S"跨度>
  • visual-block + Surround.vim的第3点应该是S",而不是s"
  • 这很酷,但这仅适用于您要在不同行上编辑的字符在每行上处于完全相同的水平位置,并且编辑的行是一个接一个的情况.我们不能在 Vim 的哪一行选择在编辑模式下输入的位置吗?我们可以在 Sublim... 编辑: 实际上第二个答案就是我要找的
  • @AndrewBobulsky,您的假设是正确的。这是映射中使用的标准符号,也是编写 Vim 时的事实标准。见:help key-notation
【解决方案2】:

上面给出了一些很好的开箱即用解决方案,但我们也可以尝试一些提供多个光标的插件,如 Sublime。

我认为这个看起来很有希望:

它似乎被放弃了一段时间,但在 2014 年有一些贡献。

它非常强大,虽然我花了一点时间来适应流程(这很像 Sublime,但仍然像 Vim 一样是模态的)。

根据我的经验,如果你安装了很多其他插件,你可能会遇到一些冲突!

此功能还有其他一些尝试:

如果您发现其中任何一项正在改进,请随时进行编辑。

【讨论】:

【解决方案3】:

在 Vim 中有几种方法可以做到这一点。不知道哪个最 类似于 Sublime Text 的。


第一个是通过多行插入模式。将光标放在 第一行的第二个“a”,按Ctrl-V,选择所有行,然后按I,然后 加上双引号。按&lt;esc&gt; 将在每一行重复操作。


第二个是通过宏。将光标放在第一个字符上,然后开始 使用qa 录制宏。 使用llll 向右移动,使用 a,放下双引号,退出插入模式,回到开头 &lt;home&gt;(或等效项)。按j 向下移动一排。 使用q 停止录制。 然后使用@a 重播宏。好几次。


以上方法对你有用吗?

【讨论】:

    【解决方案4】:

    如果您使用“全局”命令,您可以在一个在线任意行数上重复您可以执行的操作。

    :g/<search>/.<your ex command>
    

    示例:

    :g/foo/.s/bar/baz/g
    

    上面的命令查找所有包含 foo 的行,并将该行上所有出现的 bar 替换为 baz。

    :g/.*/
    

    每一行都会做

    【讨论】:

    • 这太有用了,我不知道。看起来如此强大和巧妙的命令组合。
    • 为方便起见,我编写了一个小函数,它获取光标下的单词(或视觉选择的单词),提示替换,然后运行此处描述的:g 命令。我喜欢使用/gc 来请求“确认”,这样我就可以点击yn 进行每个替换,或者a 来更改所有替换。
    【解决方案5】:
    Ctrl-v ................ start visual block selection
    6j .................... go down 6 lines
    I" .................... inserts " at the beginning
    <Esc><Esc> ............ finishes start
    2fdl. ................. second 'd' l (goes right) . (repeats insertion)
    

    【讨论】:

    • 第三步,I无法进入插入模式,你知道为什么会这样吗?
    • 尝试在没有插件的情况下加载 vim:vim -u NONE 并尝试再次执行所需的操作,可能是一些地图或插件改变了 vim 的行为。
    【解决方案6】:

    我不确定vim 在做什么,但这是一个有趣的效果。您描述所需内容的方式听起来更像是宏的工作方式 (:help macro)。像这样的东西可以用宏做你想做的事(从正常模式开始):

    1. qa:将宏录制到a寄存器中。
    2. 0w:0转到行首,w跳一个字。
    3. i"&lt;Esc&gt;:进入插入模式,插入",返回正常模式。
    4. 2e:跳转到第二个单词的结尾。
    5. a"&lt;Esc&gt;:附加一个"
    6. jq 移动到下一行并结束宏录制。

    合起来:qa0wi"&lt;Esc&gt;2ea"&lt;Esc&gt;

    现在您可以使用@a 执行宏,使用@@ 重复上一个宏。要应用于文件的其余部分,请执行 99@a 之类的操作,假设您的行数不超过 99 行,宏执行将在到达文件末尾时结束。

    这里是如何使用visual-block-mode 实现你想要的(从正常模式开始):

    1. 导航到您希望第一个引用的位置。
    2. 输入visual-block-mode,选择要影响的行,G 转到文件底部。
    3. 点击I"&lt;Esc&gt;
    4. 移动到您要插入" 的下一个位置。
    5. 您想重复刚才的操作,所以一个简单的. 就足够了。

    【讨论】:

    • 不需要 99@a。如果您希望在文件的每一行上执行宏,请尝试 :%norm! @a.
    • 没有点(它们只是句子的结尾,不是命令的一部分)
    • 9999@a 可能很难看,但它比:%norm! @a 更容易输入,而且它不会在您刚刚编辑的行上重新运行。无论如何还是很高兴知道它。 :)
    【解决方案7】:

    我的解决方案是使用这两个映射:

    map <leader>n <Esc><Esc>0qq
    map <leader>m q:'<,'>-1normal!@q<CR><Down>
    

    如何使用它们:

    1. 选择您的线路。如果我想选择接下来的 12 行,我只需按 V12j
    2. &lt;leader&gt;n
    3. 对行进行更改
    4. 确保您处于正常模式,然后按&lt;leader&gt;m

    要进行另一次编辑,您无需再次进行选择。只需按&lt;leader&gt;n,进行编辑,然后按&lt;leader&gt;m 即可申请。


    这是如何工作的:

    • &lt;Esc&gt;&lt;Esc&gt;0qq退出视觉选择,到行首开始录制宏。

    • q停止录制宏。

    • :'&lt;,'&gt;-1normal!@q&lt;CR&gt;从视觉选择的开始到结束前的行,在每一行播放宏。

    • &lt;Down&gt;回到最后一行。


    您也可以只映射相同的键,但用于不同的模式:

    vmap <leader>m <Esc><Esc>0qq
    nmap <leader>m q:'<,'>-1normal!@q<CR><Down>
    

    虽然这会影响您进行其他编辑的能力。您必须重新选择您的线路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-29
      • 2017-10-25
      • 2013-03-20
      • 1970-01-01
      • 2022-12-31
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      相关资源
      最近更新 更多