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.
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.
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>
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 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.