How do I create a dynamic abbreviation that inserts live content like the current date?
Answer
:iabbrev <expr> {trigger} {expression}
Explanation
The <expr> flag on :iabbrev turns the right-hand side into a Vimscript expression that is evaluated at expansion time rather than stored as a literal string. This lets abbreviations insert dynamic content — timestamps, random values, or anything computable — without plugins.
How it works
:iabbrev— defines an insert-mode abbreviation<expr>— tells Vim to evaluate the RHS as a Vimscript expression each time the abbreviation fires- The expression must return a string, which becomes the replacement text
Example
Add these to your vimrc:
iabbrev <expr> date strftime('%Y-%m-%d')
iabbrev <expr> dtime strftime('%Y-%m-%d %H:%M')
iabbrev <expr> uuid system('uuidgen')->trim()
In insert mode, typing date followed by a space or punctuation expands to the current date:
Before: Reviewed on date<Space>
After: Reviewed on 2026-03-10
Every expansion is freshly evaluated, so the date is always current — not frozen at startup.
Tips
- The expression runs in Vimscript, so any built-in function is available:
expand(),system(),line('.'), etc. - Use
->trim()(orsubstitute(..., '\n', '', 'g')) to strip trailing newlines fromsystem()output - To avoid expansion in certain contexts, wrap with a guard:
mode() ==# 'i' ? expr : trigger - Static abbreviations (no
<expr>) are simpler and faster — use<expr>only when the value must be dynamic