2

In Vim 8, you can open a terminal inside Vim with the term command. This opens a new buffer of type terminal inside vim. Is there any way of sending lines from other buffers to this type of buffer?

For example:

nmap <some binding> <sends the entire line under cursor to buffer of type='terminal'>

What I am trying to achieve with this is to evaluate REPL statements without using any plugins

Thanks for any help in advance!

migrated from stackoverflow.com Nov 22 '17 at 15:23

This question came from our site for professional and enthusiast programmers.

  • 4
    you can do :. term to sent current line as input to terminal to execute/evaluate. – Kent Nov 2 '17 at 12:05
  • 3
    Have you tried term_sendkeys()? – Luc Hermitte Nov 22 '17 at 16:01
3

An awkward solution
Copy content into a register from an editing window and paste in to the :terminal window with <CTRL-W> " {reg} to run it.

Example with one editing buffer and one :terminal buffer running bash:

  • text content in editing window
    echo hello

  • cmd to copy the content to the 0 register
    :vipy

  • move to the terminal window
    <CTRL-W> W

  • paste 0 register into terminal window
    <CTRL-W> "0

  • :terminal output
    hello

  • move back to editing window
    <CTRL-W> W

... continue editing...

This also works for python REPL and probably for language REPL.

Here is a simpler alternative
Using term_sendkeys :

  • open a vim terminal and start the REPL
    check which buffer the terminal is in with :ls
    this example assumes the terminal is in buffer 2

  • cmd to copy the content to the " register (the unamed register) and paste/run in the terminal
    :%y | call term_sendkeys(2, @")

The command can then be mapped like this example:
nnoremap <leader>sk :%y \| :call term_sendkeys(2, @")<CR>

There is also at least two plugins available.
(I haven't tried them):
https://vimawesome.com/plugin/vim-sendtowindow
and
https://github.com/habamax/vim-sendtoterm

1

As Luc Hermitte pointed out, you can use :h term_sendkeys to send commands to terminal buffer, the hard part is to manage the terminal buffer:

function s:exec_on_term(lnum1, lnum2)
  " get terminal buffer
  let g:terminal_buffer = get(g:, 'terminal_buffer', -1)
  " open new terminal if it doesn't exist
  if g:terminal_buffer == -1 || !bufexists(g:terminal_buffer)
    terminal
    let g:terminal_buffer = bufnr('')
    wincmd p
  " split a new window if terminal buffer hidden
  elseif bufwinnr(g:terminal_buffer) == -1
    exec 'sbuffer ' . g:terminal_buffer
    wincmd p
  endif
  " join lines with "\<cr>", note the extra "\<cr>" for last line
  " send joined lines to terminal.
  call term_sendkeys(g:terminal_buffer,
        \ join(getline(a:lnum1, a:lnum2), "\<cr>") . "\<cr>")
endfunction

command! -range ExecOnTerm call s:exec_on_term(<line1>, <line2>)
nnoremap <leader>ex :ExecOnTerm<cr>
vnoremap <leader>ex :ExecOnTerm<cr>

read comment as explanation

usage

execute single line in normal mode, multiple lines in visual mode.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy