29

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?

5 Answers 5

32

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

7
  • With this solution, I experience this problem. Would you know of a way around it? Commented Apr 19, 2018 at 10:18
  • The BufEnter autocmd looks like it does not have this problem. Commented Apr 19, 2018 at 10:49
  • This did not work for me, but this answer (vi.stackexchange.com/a/22956/13656) did Commented Jul 22, 2022 at 15:16
  • The first autocmd only worked for me when I switched the command to silent! normal i.
    – Cookie04
    Commented Aug 18, 2023 at 18:57
  • for those using lua vim.api.nvim_create_autocmd({ "TermOpen", "WinEnter term://*" }, { command = "startinsert" }) ```
    – Will Munn
    Commented Sep 7, 2023 at 13:50
17

On neovim, you can do:

          autocmd TermOpen * startinsert

Found in :help :terminal .

3

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

:au BufEnter * if &buftype == 'terminal' | :startinsert | endif
2
  • 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
    Commented Feb 6, 2018 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
    Commented Mar 2, 2018 at 3:52
3

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

If you use toggleterm, it may conflict with option persist_mode = true as it will revert to normal mode upon entering terminal.

Anyway you don't need this autocommand if you use toggleterm with options: start_in_insert = true, persist_mode = false.

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
    Commented Jan 3 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" Commented Jan 3 at 22:56
  • Fair! Totally forgot the OP had this (odd) goal
    – D. Ben Knoble
    Commented Jan 4 at 14:26
  • It does not work for me in neovim. When I am in terminal, press Enter, then Escape to exit insert mode. Then I switch to another window and go back to terminal. It stays in normal mode.
    – rofrol
    Commented Apr 29 at 12:54
  • The issue was with toggleterm.nvim. I have modified the answer.
    – rofrol
    Commented Apr 29 at 16: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"
2
  • Note that silent needs to be silent! and go before the actual command, e.g. I ended up with autocmd BufEnter <buffer> silent! exec "normal! i". (Vim 8.2) Commented Jun 3, 2021 at 0:29
  • Thanks ! I've update the post ;)
    – aemonge
    Commented Jun 10, 2021 at 8:08

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.