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)?
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". – Ingo Karkat Nov 25 '16 at 10:41
-
"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
. – René Nyffenegger Nov 25 '16 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.