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!

  • 7
    you can do :. term to sent current line as input to terminal to execute/evaluate.
    – Kent
    Commented Nov 2, 2017 at 12:05
  • 3
    Have you tried term_sendkeys()? Commented Nov 22, 2017 at 16:01

4 Answers 4


Here is a solution using Vim's 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>

Plugin Options:
There are also many plugins available.

This one is the next step up from manual steps.
I've tried it and it works and was updated in September of 2020.

Also, its README includes an extensive list of related plugins. A few of these have continued to be updated in 2021.

For those interested, here is a more manual solution
Copy content into a register from an editing window and paste into 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

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

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

  • :terminal output

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

... continue editing...

This also works for python REPL and probably for other languages' REPLs.


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)
    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
  " 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>")

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

read comment as explanation


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


I wanted to send lines from a buffer into an open vim terminal, and this seemed like a possible solution:

" \tt will open a new terminal window
nnoremap <leader>tt :botright terminal<CR>

" \tr will send text to the window
nnoremap <leader>tr yy \| :call term_sendkeys(term_list()[0], @")<CR>
vnoremap <leader>tr y \| :call term_sendkeys(term_list()[0], @")<CR>
:call term_list()[0]->term_sendkeys(getline('.') .. "\<CR>")

After sending first line, do, @: to repeat for next and then @@ for rest. Can be mapped to binding or user command if used frequently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.