最近,NeoVim有一个附加组件,它允许在vim缓冲区中打开终端。这具有将文本从一个vim窗口发送到另一个副本的吸引力,例如,类似于REPL的行为。

过去,我使用tmux进行这种配置。但是现在我只想使用NeoVim尝试一下。

我的问题是-如何将一个vim拆分的文本块发送到另一个?或许更确切地说-如何使选择文本,拉动文本,更改拆分然后粘贴的顺序自动化?

#1 楼

基本上,当您选择了文本时,您要重新映射要复制的键序列,切换到终端,粘贴,然后可能再切换窗口并重新选择文本。如果您打开了两个拆分,则看起来应该像这样:

vnoremap <F5> y<c-w>wp<c-w>pgv
"explanation:
xnoremap <F5>                   Remap F5 in visual/select mode (could be any key combo)
              y                 copy selected text
               <c-w>w           switch to next window
                     p          paste (for terminals this sends the text to the terminal)
                      <c-w>p    switch to previous window
                            gv  reselect


如果拆分超过两个,并且终端不在选择文本的位置,您可能想要使用适合您的布局的其他映射(即,<c-w>t移至左上角的窗口),或者您想编写一个遍历所有窗口并找到正确窗口的函数。

评论


从我可以看到,在终端缓冲区中使用p不会进入终端模式,因此以下 不必要。 (也就是说,它也是完全无害的。)

–tommcdo
15年3月28日在0:27

@tommcdo不错的电话,我自己还没有尝试过该功能,因此只是在尝试一下。我将删除该部分。

–马特·博姆(Matt Boehm)
15年3月28日在4:32

#2 楼

Neovim终端缓冲区始终具有关联的作业ID,因此一种方法是使用作业控制API发送文本。将此添加到您的vimrc中:

augroup Terminal
  au!
  au TermOpen * let g:last_terminal_job_id = b:terminal_job_id
augroup END


将最后创建的终端的作业ID保存到g:last_terminal_job_id变量中。然后,您可以创建一些函数/命令/映射,这些函数将使用jobsend函数发送数据,下面是一个示例:

function! REPLSend(lines)
  call jobsend(g:last_terminal_job_id, add(a:lines, ''))
endfunction

command! REPLSendLine call REPLSend([getline('.')])

nnoremap <silent> <f6> :REPLSendLine<cr>


以上内容将发送当前行,但是您可以扩展它以发送视觉选择。

#3 楼

Neoterm是为此目的而开发的neovim插件。它实现了一个新命令:TREPLSend,它将接受当前行并将其发送到终端窗口。适用于基本的bash和任何具有REPL模式的语言。

#4 楼

除了此处的答案外,我还为此目的实现了一个插件:vim-sendtowindow。

它提供了一个send-to-window运算符,可以将其与任何vim motion结合使用,以便选择文本发送到相邻窗口。此外,它方便地将光标定位在发送的文本之后,并且可以重复点。

下面的一个小示例: