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

How do I run a dynamically constructed Ex command or pass special keys to :normal?

Answer

:execute

Explanation

:execute evaluates a string as an Ex command, letting you build commands dynamically or embed special key sequences (like <CR> or <Esc>) as literal characters. It is the standard way to run computed commands in mappings, autocommands, and scripts.

How it works

  • :execute "command" — evaluates the string and runs it as an Ex command
  • String concatenation (.. in Vim 8+, or . in older Vim) builds the command dynamically
  • Special key names inside double quotes are interpreted: "\<CR>" becomes an actual Enter key
  • This is the key difference from :normal: :normal ggjj<CR> cannot send a real Enter key, but :execute "normal! gg\<CR>" can

Example

Search for the word under the cursor dynamically:

:execute "normal! /" . expand('<cword>') . "\<CR>"

This constructs /keyword and sends Enter as a real keystroke — something :%s patterns or literal :normal cannot do cleanly.

Or prompt for a pattern and substitute throughout the file:

:execute "%s/" . input('Find: ') . "/" . input('Replace: ') . "/gc"

Tips

  • Always use normal! (with bang) inside execute to ignore user mappings
  • Use shellescape() when building shell commands with ! or system()
  • execute can concatenate a list: :execute join(['%s', 'foo', 'bar', 'g'], '/')
  • In Neovim Lua, use vim.cmd(string.format(...)) for the same pattern

Next

How do I use capture groups in Vim substitutions to rearrange or swap matched text?