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?

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>
| improve this answer | |
  • Awesome! Thank you very much. – Phil R Oct 4 '19 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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