How do I get the current Vim mode as a string for use in expression mappings or the statusline?
Answer
mode()
Explanation
The mode() function returns a short string identifying the current editing mode — 'n' for Normal, 'i' for Insert, 'v' for Visual character-wise, 'V' for Visual line-wise, and so on. This enables conditional logic inside <expr> mappings and statusline expressions, letting a single definition adapt to context.
How it works
mode()returns a one- or two-character string representing the active mode- Common values:
'n'(Normal),'i'(Insert),'v'(Visual char),'V'(Visual line),"\<C-v>"(Visual block),'c'(Command-line),'R'(Replace),'t'(Terminal) - Passing
1as an argument (mode(1)) returns a longer string with extra info (e.g.'niI'wheniis pending) - Most useful inside
<expr>mappings (which evaluate the RHS as an expression) and%{...}statusline segments
Example
Make <CR> insert a blank line in Normal mode but act normally in other modes:
nnoremap <expr> <CR> mode() ==# 'n' ? 'o<Esc>' : "\<CR>"
Display a human-readable mode label in the statusline:
function! ModeLabel() abort
let l:map = {'n': 'NORMAL', 'i': 'INSERT', 'v': 'VISUAL',
\ 'V': 'V-LINE', "\<C-v>": 'V-BLOCK', 'R': 'REPLACE', 'c': 'CMD'}
return get(l:map, mode(), mode())
endfunction
set statusline=%{ModeLabel()}\ %f
Tips
- Always use
==#(case-sensitive equality) when comparing mode strings —mode()values are case-sensitive - In Neovim,
:echo mode()works interactively; entering:returns'c', confirming the function works even in Command-line mode - The companion
visualmode()function returns the type of the most recent Visual selection ('v','V', or"\<C-v>") even after you leave Visual mode — useful in operator-pending functions that need to know the selection type