Within a function, is there a way to determine if vim is in insert mode (or was in insert mode prior to calling the function)?

3 Answers 3


Something must have invoked your function. Setting the (new in Vim 8.0) asyncronous timers aside, this will be either

  • a custom command, which cannot be invoked from insert mode, only command-line mode
  • a mapping
  • an :autocmd event

For the latter, you can split into two separate :autocmds, and pass an isInsertMode flag into your function:

autocmd CursorHold,CursorHoldI * call MyFunc()

turns into

autocmd CursorHold  * call MyFunc(0)
autocmd CursorHoldI * call MyFunc(1)

For mappings, you can pass a similar flag, or a character representing the mode (to also handle visual mode and so on):

:nnoremap <F2> :call MyFunc('n')<CR>
:vnoremap <F2> :<C-u>call MyFunc('v')<CR>
:inoremap <F2> <C-o>:call MyFunc('i')<CR>

That is the canonical approach, and should work for most use cases. If you have a really special need, please elaborate in your question.


There is mode() function which can be used in some contexts (not thoroughly documented) with the following description:

mode([expr])    Return a string that indicates the current mode.
                  i       Insert

So, when it works, check for insert mode in your function can look like this:

if mode() == 'i'
    " in insert mode
  • 2
    That only works under some special circumstances (as part of statusline evaluation, or map-expr, or a remote invocation). Its help even mentions this: In most other places it always returns "c" or "n". Commented Nov 25, 2016 at 10:41
  • 1
    "In most other places" is a rather vague term, unfortunately. For the CursorMovedI and CursorMoved events which I am particularly interested in, mode() seems to work. Within the InsertEnter event, however, mode() returns in fact n. Commented Nov 25, 2016 at 10:56

Jist of hinging behavior on the mode that you are in:

The reason that determining what mode you're in is difficult is because you're trying to decide something in a place where that information is generally not kept.

So move upstream and put your hinge on mode in the nnoremap, inoremap, vnoremap, etc, like this:

nnoremap jj :call DecoupleDilithiumMatrix()
nnoremap jk :call EjectWarpCore()

Then you can put your mode-specific code in the functions.

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.