将缓冲区发送到Vim 8中正在运行的终端窗口

Sta*_*vin 5 vim terminal

是否可以将缓冲区的内容发送到正在运行的终端窗口。该窗口可以运行,例如用于python代码的REPL。

我的意思是VIM的新终端功能,而不是外部插件或以前的版本。

Pet*_*ker 6

您可以term_sendkeys()用来将数据发送到终端缓冲区。但是,有一些注意事项:

  • 需要捕获数据以term_sendkeys()经常使用,这是通过拉动文本
  • 需要知道要发送到哪个终端缓冲区

这是一些代码,可以简化并自动执行发送到终端缓冲区的工作流程。放入vimrc文件或制作一个小插件。

augroup send_to_term
  autocmd!
  autocmd TerminalOpen * if &buftype ==# 'terminal' |
        \   let t:send_to_term = +expand('<abuf>') |
        \ endif
augroup END


function! s:op(type, ...)
  let [sel, rv, rt] = [&selection, @@, getregtype('"')]
  let &selection = "inclusive"

  if a:0 
    silent exe "normal! `<" . a:type . "`>y"
  elseif a:type == 'line'
    silent exe "normal! '[V']y"
  elseif a:type == 'block'
    silent exe "normal! `[\<C-V>`]y"
  else
    silent exe "normal! `[v`]y"
  endif

  call s:send_to_term(@@)

  let &selection = sel
  call setreg('"', rv, rt)
endfunction

function! s:send_to_term(keys)
  let bufnr = get(t:, 'send_to_term', 0)
  if bufnr > 0 && bufexists(bufnr) && getbufvar(bufnr, '&buftype') ==# 'terminal'
    let keys = substitute(a:keys, '\n$', '', '')
    call term_sendkeys(bufnr, keys . "\<cr>")
    echo "Sent " . len(keys) . " chars -> " . bufname(bufnr)
  else
    echom "Error: No terminal"
  endif
endfunction

command! -range -bar SendToTerm call s:send_to_term(join(getline(<line1>, <line2>), "\n"))
nmap <script> <Plug>(send-to-term-line) :<c-u>SendToTerm<cr>
nmap <script> <Plug>(send-to-term) :<c-u>set opfunc=<SID>op<cr>g@
xmap <script> <Plug>(send-to-term) :<c-u>call <SID>op(visualmode(), 1)<cr>
Run Code Online (Sandbox Code Playgroud)

您可以设置自己的映射。例:

nmap yrr <Plug>(send-to-term-line)
nmap yr <Plug>(send-to-term)
xmap R <Plug>(send-to-term)
Run Code Online (Sandbox Code Playgroud)

现在,您可以:[range]SendToTerm用于将[range]行的行发送到选项卡页中的上次使用的终端缓冲区。您还可以yrr用于发送行,yr{motion}发送{motion}文本或用于R将可视选择的文本发送到终端缓冲区。注意:您必须在当前选项卡页面中事先打开终端缓冲区。