vimtricks.wiki Concise Vim tricks, one at a time.

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() (or substitute(..., '\n', '', 'g')) to strip trailing newlines from system() 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

Next

How do I define a mapping that only takes effect if the key is not already mapped?