I’m trialing a move to MacVim, and with it, moving to Vim 8’s new built-in terminal emulator.
My purpose in doing this is to see how GUI Vim is looking these days and to see if GUI Vim running a terminal emulator can actually compete with a terminal emulator running Vim for my development uses.
Why use GUI Vim?
- I like that tab management looks nice and I can re-order tabs easily
- No dealing with terminal color limitations
- Less keybinding weirdness, want to bind to Meta/Option/Alt? Easy,
- Proper bold/italics
Why have a terminal inside GUI Vim?
- Navigating terminal output using Vim bindings
- Easily yank/put between buffers and terminal, no system clipboard involved
Honestly this argument is kind of weak. If you like tinkering with your tools though, carry on!
This launches a horizontal split with a terminal taking up precious vertical space.
Let’s define some keybindings that are more comfortable. I use
<space> as my leader,
and tend to group related commands under a prefix. I chose
<leader>t to be my
" terminal in tab nnoremap <leader>tt :tab term<CR> " terminal in current window nnoremap <leader>tc :term++curwin<CR> " terminal in vertical split nnoremap <leader>tv :vert term<CR>
These cover my use cases pretty well, I never use horizontal split terminals.
How do you get out of terminal windows?
:help Terminal-Mode shows that
CTRL-W basically works as expected. You can move to different windows,
tabs, or escape normal mode commands by prefixing with
CTRL-W. You can
escape to terminal normal mode using
CTRL-W N, but I found this annoying.
If you don’t really need escape inside your terminal sessions you can bind it to escape terminal mode (this is from the Vim docs!).
tnoremap <Esc> <C-W>N
Passing through special keys
The most annoying thing I find with these built-in terminals is how they always seem to break shell bindings.
I’ve learned bits and pieces of emacs-ish bindings available in common shells.
<M-b> goes backwards a word in most shells and
<M-f> goes forward
a word. Also,
<CTRL-W> deletes backwards one word.
These are totally broken in Vim’s built-in terminal. Obviously
stolen by Vim since it is using
<CTRL-W> to escape to normal mode.
<M-f> will leave you frustrated with a bunch
of special characters like so
I don’t really have a great solution for
<CTRL-W>, I don’t want to make
drastic changes to how Vim sets up these bindings by default, so I’m just
getting used to hitting
<M-BS> to delete a word while avoiding
I do have a solution for my
<M-f> woes though! Vim’s docs have
a little function definition
to help with passing special keys.
" Allow us to create <M-*> bindings set macmeta " Remap to call send_term function tmap <expr> <M-b> SendToTerm("\<Esc>b") tmap <expr> <M-f> SendToTerm("\<Esc>f") func SendToTerm(what) call term_sendkeys('', a:what) return '' endfunc
This lets Vim actually pass the correct terminal escape code to get these shortcuts working as expected again.
I’m sure I’ll run into some more annoyances soon, but so far this is working out pretty well for me, and there’s a clear path to adding additional escape sequences for other broken shortcuts. I will say that being able to navigate terminal output and rapidly yank/put has really been an improvement.
Want to know what keycode is being sent by a terminal to your application?
cat then hit the key combination, you’ll see the keycode output.