28

I have the following mappings to make it easy to move out of a terminal pane in Neovim:

tnoremap <C-h> <C-\><C-n><C-w>h
" Workaround since <C-h> isn't working in Neovim right now
tnoremap <C-w>h <C-\><C-n><C-w>h
tnoremap <C-j> <C-\><C-n><C-w>j
tnoremap <C-k> <C-\><C-n><C-w>k
tnoremap <C-l> <C-\><C-n><C-w>l

The only problem is that when I move back into the terminal pane, I have to press i to get back into insert mode. I always want it to be in insert mode when I move into a Neovim pane that is running terminal. What's the best way to achieve this?

Vivian De Smedt
  • 16,336
  • 3
  • 18
  • 37
aharris88
  • 1,847
  • 2
  • 17
  • 22

5 Answers5

31

A terminal buffer name always starts with term://:

autocmd BufWinEnter,WinEnter term://* startinsert

Note that this will always put you in insert mode when you move to the terminal window, regardless of the mode you were using when leaving the window.


You can also use a similar autocommand to always get back in normal mode when you leave the terminal window, no matter how you leave this window:

autocmd BufLeave term://* stopinsert

Benoît Faucon
  • 426
  • 4
  • 4
16

On neovim, you can do:

          autocmd TermOpen * startinsert

Found in :help :terminal .

guntbert
  • 1,245
  • 1
  • 13
  • 27
Nephilim
  • 261
  • 3
  • 4
3

Entering a terminal buffer sets buftype to terminal, you can actually use this instead:

:au BufEnter * if &buftype == 'terminal' | :startinsert | endif
statox
  • 49,782
  • 19
  • 148
  • 225
  • 1
    I found that :startinsert does not work for native vim 8 terminals as of this post. It is actually explicitly stated in :help terminal that, ":startinsert is ineffective." I found that exec 'normal! i' works instead. – Kevin Feb 06 '18 at 15:11
  • 1
    "I found that :startinsert does not work for native vim 8 terminals as of this post." That's sad. Vim has lots to learn from NeoVim. – trusktr Mar 02 '18 at 03:52
2

A lot of answers in this thread do not support reopening terminal buffer back. This autocmd will always enter terminal mode upon opening the terminal buffer.

In Lua:

vim.api.nvim_create_autocmd({ "TermOpen", "BufEnter" }, {
    pattern = { "*" },
    callback = function()
        if vim.opt.buftype:get() == "terminal" then
            vim.cmd(":startinsert")
        end
    end
})

Or in Vimscript:

:au TermOpen,BufEnter * if &buftype == 'terminal' | :startinsert | endif
ivanjermakov
  • 143
  • 5
  • That may not be desirable, though: perhaps I entered terminal normal mode, switched windows, and came back (and I don't want to lose my place by jumping to the input part of the job). – D. Ben Knoble Jan 03 '24 at 21:16
  • 2
    @D.BenKnoble I agree, but the author mentioned "I always want it to be in insert mode when I move into a neovim pane that is running terminal" – ivanjermakov Jan 03 '24 at 22:56
  • Fair! Totally forgot the OP had this (odd) goal – D. Ben Knoble Jan 04 '24 at 14:26
1

Or even slightly better:

  function! TerminalOptions()
    " /* folded code */
    silent! au BufEnter <buffer> startinsert!
    silent! au BufLeave <buffer> stopinsert!
  endfunction
  au TerminalOpen * call TerminalOptions()

Which the <buffer> will make the au command to be applied locally, so only for the termial buffer type. This is also usefull for changing so setting for the terminal only. Such as swtich from relative lines to absolute ;)

Also..... I cant get :startinsert to work, even if all docs point to that. I had to do the following:

    au BufEnter <buffer> exec "normal! i"
aemonge
  • 111
  • 4