【问题标题】:How can I save a text block in visual mode to a file in Vim?如何将可视模式下的文本块保存到 Vim 中的文件中?
【发布时间】:2010-10-22 10:38:13
【问题描述】:

标题非常具有描述性。以防万一,我举个例子:

START BLOCK1
something
END BLOCK1

START BLOCK2
something
somenthing...
END BLOCK2
  1. 我在可视模式下选择BLOCK1
  2. 我按 y 拉动它
  3. 如何将拉取的BLOCK1 保存到其他文件?

【问题讨论】:

    标签: file vim save selection


    【解决方案1】:

    除了上面selected的回答,

    • 使用鼠标选择(1)时,

    • 以及注释中提到的只复制整行的问题 @dronus 的一部分,当只是想部分复制行 (2) 时:

    (1) 在我的基于 Debian 的 DietPi (Raspberry PI) 系统中,当在我的 Ubuntu 16.04 工作站上使用鼠标进入并选择“视觉模式”时,vim 的行为与上面的首选解决方案略有不同。那么

    • y 拉它

    但是如果我输入 ':' 作为命令,它不会与

    一起显示
    '<,'>
    

    我可以简单地添加我的

    w new.txt
    

    之后。所以我只是自己输入了它,它确实有效:

    '<,'>w new.txt
    

    并且它将整行复制内容复制到我的文件'new.txt',而''将其重定向到写入命令的引用文件。

    (2) 对于不粘贴部分行的问题,就像在@dronus comment 中提到的那样,this 解决方案(选择的,第一个替代方案)对我有用:

    编辑第一个文件,拉出你想要的文本。然后从 vi (:e /path/to/other/file) 中打开第二个文件并粘贴它(通过键入 p)。保存它(如上面的 ':w new.txt'。

    然后它只会复制用鼠标或“y”标记的部分行。

    [编辑] 在我的 Ubuntu 系统上:有时通过鼠标选择不会在 vim 中进入“视觉模式”。然后可以使用上下文菜单选择正常的复制/粘贴...我还没有找到 Ubuntu 将其行为从“客户端代理行为”更改为“主机”行为的原因(Ubuntu 将 ssh bash 窗口托管到我的“客户')...

    【讨论】:

      【解决方案2】:

      Vim 获取视觉选择并保存到文件中:

      function! Get_visual_selection()
          #Get the position of left start visual selection
          let [line_start, column_start] = getpos("'<")[1:2]
          #Get the position of right end visual selection
          let [line_end, column_end] = getpos("'>")[1:2]
          #gotta catch them all.
          let lines = getline(line_start, line_end)
          if len(lines) == 0
              return ''
          endif
          #edge cases and cleanup.
          let lines[-1] = lines[-1][: column_end - 2]
          let lines[0] = lines[0][column_start - 1:]
          return join(lines, "\n")
      endfunction
      
      function Save_visually_selected_text_to_file()
          let selected_text = Get_visual_selection()
          call writefile(split(selected_text, "\n"), "/tmp/something.txt")
      endfunction
      
      #the c-u does a union of all lines in visual selection.
      #this goes in the vimrc
      vnoremap <F10> :<c-u>call Save_visually_selected_text_to_file()<cr>
      

      【讨论】:

        【解决方案3】:

        基于@chenkaie 的变体,对我来说效果很好:

        let mapleader = "," let g:mapleader = "," vmap <leader>y y:new ~/.vbuf<CR>VGp:x<CR> nmap <leader>p :r ~/.vbuf<CR>

        【讨论】:

          【解决方案4】:

          类似于@songz 的解决方案,我更喜欢使用 ":new" 这样做

          vmap <C-c> y:new ~/.vimbuf<CR>VGp:x<CR>:!pbcopy < ~/.vimbuf<CR><CR>
          

          【讨论】:

          • 据我所知,pbcopy 仅存在于 OSX 上。 Linux 和其他系统上有类似的程序,但它们的名称不同,工作方式也不同。
          • 是的,它只有在 pbcopy 可执行文件的情况下才有效 :) 所以完全没有害处
          【解决方案5】:

          就像 cmets 中提到的 @dronus 一样,:w !pbcopy 建议无法正确复制,因为它复制了整行。如果我只想复制一行中的 url,我将无法做到。这是您可以添加到 .vimrc 文件中的一行,这样每次您按 CTRL-C 时,vim 中选定的行都会被复制到剪贴板:

          map <C-c> y:e ~/clipsongzboard<CR>P:w !pbcopy<CR><CR>:bdelete!<CR>
          

          如果您想阅读有关此功能的详细信息,可以在 my blog 上阅读有关此内容的信息

          它与@rmeador 建议的实现相同。

          【讨论】:

            【解决方案6】:

            选择您要保存的文本,在线条视觉或块视觉模式下,然后

            :w new.txt
            

            这就是您输入的内容,但您实际上不会看到上面的内容。当您按下: 时,您将转到命令行,该命令行将自动填写选择信息。它看起来像这样:

            :'<,'>
            

            只需继续输入其余部分 (w new.txt) 即可获得

            :'<,'>w new.txt
            

            ...然后按回车键。

            【讨论】:

            • 这并没有提供预期的结果,因为它只写了整行,而忽略了行内的选择开始和结束位置。有什么解决办法吗?否则我想再次提出主要问题。
            • @dronus - 我不太明白你在问什么。据我所知,这可以满足 OP 的要求。
            • 如果您在任何非线视觉模式下选择,:w 仍会写出所选范围所触及的完整行,但不会写出行内开始或结束的确切范围。例如,如果您在块选择模式下选择窄列,或者在可视选择模式下选择一行的一部分,则整行将由:w 写入,即使y 会复制该行的正确部分。
            • @dronus - 啊,好吧。对,那是正确的。但是,虽然我不能为别人说话,但它所做的是对我的预期行为。
            【解决方案7】:

            选择块后,您可以:'&lt;,'&gt;w other-file,这将只将选定的块写入other-file。在可视模式下点击: 应该已经将'&lt;,'&gt; 放入命令行中,因此您实际上只需要输入:w other-file

            【讨论】:

            • Vim 总是选择整行用于管道到外部命令,因此您可以使用 unix/cygwin 'cut' 命令选择选择中每一行的 N 到 M 列的矩形::'&lt;,'&gt;w !cut -cN-M &gt; new.txt .对投票率最高的答案感到惊讶,而读者似乎不理解这个问题。
            • @mosh 但是当所选文本未与列对齐时,这也不起作用。
            【解决方案8】:

            可能有更简单的方法可以做到这一点,但我要做的是创建一个新缓冲区(或选项卡),然后将其粘贴到 p 中。您可以使用:new 创建一个新缓冲区或使用:tabnew 创建一个新选项卡。您可以像往常一样使用:w filename 将缓冲区/选项卡写入文件。

            【讨论】:

            • 请务必删除顶部多余的行! (粘贴到空缓冲区会在顶部创建一个额外的行,或者如果使用P,则在底部创建一个额外的行。)
            猜你喜欢
            • 2010-10-22
            • 2013-09-18
            • 2011-11-16
            • 1970-01-01
            • 2012-09-06
            • 2019-02-16
            • 1970-01-01
            • 2011-09-07
            • 1970-01-01
            相关资源
            最近更新 更多