最近,NeoVim有一个附加组件,它允许在vim缓冲区中打开终端。这具有将文本从一个vim窗口发送到另一个副本的吸引力,例如,类似于REPL的行为。
过去,我使用tmux进行这种配置。但是现在我只想使用NeoVim尝试一下。
我的问题是-如何将一个vim拆分的文本块发送到另一个?或许更确切地说-如何使选择文本,拉动文本,更改拆分然后粘贴的顺序自动化?
最近,NeoVim有一个附加组件,它允许在vim缓冲区中打开终端。这具有将文本从一个vim窗口发送到另一个副本的吸引力,例如,类似于REPL的行为。
过去,我使用tmux进行这种配置。但是现在我只想使用NeoVim尝试一下。
我的问题是-如何将一个vim拆分的文本块发送到另一个?或许更确切地说-如何使选择文本,拉动文本,更改拆分然后粘贴的顺序自动化?
Answers:
基本上,当您选择了文本时,您想要重新映射要复制的键序列,切换到终端,粘贴,然后可能再切换窗口并重新选择文本。如果您打开了两个拆分,则看起来应该像这样:
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
移至左上角的窗口),或者想要编写一个遍历所有窗口并找到正确窗口的函数。
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>
上面将发送当前行,但您可以扩展它以发送视觉选择。
除了这里的答案,我还为此目的实现了一个插件:vim-sendtowindow。
它提供了一个发送到窗口的运算符,该运算符可以与任何vim运动结合使用,以选择要发送到相邻窗口的文本。另外,它方便地将光标定位在发送的文本之后,并且可以重复点。
下面是一个小例子:
p
在终端缓冲区中使用不会进入终端模式,因此以下内容<C-\><C-N>
没有必要。(也就是说,它也完全无害。)