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
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 :autocmd
s, 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
endif
-
2That 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". Nov 25, 2016 at 10:41
-
1"In most other places" is a rather vague term, unfortunately. For the
CursorMovedI
andCursorMoved
events which I am particularly interested in,mode()
seems to work. Within theInsertEnter
event, however,mode()
returns in factn
. 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.