For a while, I'd been using :nnoremap <C-H> <C-W>h and :tnoremap <C-H> <C-W>h, et. al. to switch windows. This was working great, so when I started using tabs, I decided to expand this mapping to also switch tabs when I reached the edge of the screen. To do that, I wrote the following:

function! WinTabSwitch(direction)
    let info = getwininfo(win_getid())[0]
    if a:direction == 'h' && info.wincol <= 1
        execute 'tabprev|99wincmd l'
    elseif a:direction == 'l' && info.wincol + info.width >= &columns
        execute 'tabnext|99wincmd h'
        execute 'wincmd '.a:direction

nnoremap <silent> <C-H> :call WinTabSwitch('h')<CR>
nnoremap <silent> <C-J> :call WinTabSwitch('j')<CR>
nnoremap <silent> <C-K> :call WinTabSwitch('k')<CR>
nnoremap <silent> <C-L> :call WinTabSwitch('l')<CR>

This works great, except when I'm trying to leave a terminal window. To fix that, I use these mappings,

tnoremap <silent> <C-H> <C-W>N:call WinTabSwitch('h')<CR>
tnoremap <silent> <C-J> <C-W>N:call WinTabSwitch('j')<CR>
tnoremap <silent> <C-K> <C-W>N:call WinTabSwitch('k')<CR>
tnoremap <silent> <C-L> <C-W>N:call WinTabSwitch('l')<CR>

but the unfortunate side effect is that the terminal window is left in Terminal-Normal mode. Is there a way to either

  1. return to Terminal-Job mode after leaving the terminal window (After reading :h Terminal-Normal, I have my doubts.), or
  2. call the function without leaving Terminal-Job mode?

1 Answer 1


Sure—use <C-w>: in your terminal mappings to get a colon command line instead of "escaping" to normal mode:

tnoremap <silent> <C-H> <C-W>:call WinTabSwitch('h')<CR>
  • Awesome! Thank you very much.
    – Phil R
    Oct 4, 2019 at 12:42
  • saved my day, thanks
    – caltuntas
    Aug 12, 2023 at 12:40

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.