1

I am trying to implement toggling of the Vim terminal like VS Code by doing <C-~>. But am not sure how to go about it. I find executing :term to open and to close tedious. I figured having a conditional mapping that checks if the terminal is already open, then deciding to open or close the terminal based on that information.

3
  • what terminal do you use?
    – Mass
    Commented Jan 23, 2022 at 1:08
  • The built in vim terminal Commented Jan 23, 2022 at 1:09
  • sorry, I mean what terminal do you use to run vim itself?
    – Mass
    Commented Jan 23, 2022 at 21:46

4 Answers 4

0

Since Vim doesn't actually recognize the <C-~> key sequence, you will have to choose another sequence. For example, if you wanted it to be <M-~> you could do:

nnoremap <M-~> :terminal<CR>
vnoremap <M-~> <ESC>:terminal<CR>
inoremap <M-~> <ESC>:terminal<CR>

This, unfortunately, will only open a terminal, not "toggle" the terminal. To do that it gets more complicated:

nnoremap <M-~> :call TermToggle()<CR>
vnoremap <M-~> <ESC>:call TermToggle()<CR>
inoremap <M-~> <ESC>:call TermToggle()<CR>
tnoremap <M-~> exit<CR>

function! TermToggle()
    if term_list() == []
        terminal
    else
        for term in term_list()
            call term_sendkeys(term, "exit\<cr>")
        endfor
    endif
endfunction

Even that isn't perfect, because if you have an application running in the terminal or you have typed any characters on the command line and left them, it will not properly exit since it just "feeds" the command exit to the terminal.

0

This is highly dependent on the specific terminal emulator you're using to run vim. If your terminal supports modifyOtherKeys mode (xterm, gnome-terminal), then this will work.

Otherwise, it is difficult. Some terminals allow overriding arbitrary key codes, for instance you could map to some unused key, e.g., setting it to <esc>OM in the terminal and then,

nnoremap <f26> :<c-u>terminal<cr>
1
  • I've tried to get Vim to recognize the <C-~> key sequence in multiple terminals (that do support modifyOtherKeys) and in gVim, and was unsuccessful in all of them. Maybe I'm missing something?
    – Heptite
    Commented Jan 24, 2022 at 5:29
0

Assuming you don't want to exit but instead just close the terminal window, you could try something like

function ToggleTerm() abort
  const terms = term_list()
  if empty(terms)
    " no terminals, make one
    botright terminal
  else
    const term = terms[0]
    if bufwinnr(term) < 0
      " terminal hidden, open it
      execute 'botright sbuffer' term
    else
      " terminal open, close all windows showing it in the tab
      for win_id in win_findbuf(term)
        let win_nr = win_id2win(win_id)
        if win_nr > 0
          execute win_nr 'close'
        endif
      endfor
    endif
  endif
endfunction

Map a key to this as described elsewhere. It will open a terminal on the bottom if none exists; otherwise, if a terminal is open, it will close all windows in the current tab page that are showing the first open terminal. If a terminal exists but is hidden by close, it will open that.

0

<C-`> isn't valid. I use this:

nnoremap <Leader>t :bel term<CR>
tnoremap <Leader>t exit<CR>

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.