How do I run normal mode commands in a script or macro without user mappings interfering?
Answer
:normal!
Explanation
The :normal! command (with !) executes normal mode keystrokes exactly as Vim defines them, ignoring any user-defined mappings. Without the !, :normal applies your mappings — which can cause scripts and macros to break silently if you've remapped common keys.
How it works
:normal {keys}— runs the keys as if typed, respecting user mappings (like pressing keys interactively):normal! {keys}— runs the keys using built-in Vim definitions only, bypassing allmap,nmap,nnoremap, etc.
This distinction matters because many users remap movement keys, w, b, e, or even j/k. If your function or global command uses :normal and the user has remapped w to something else, the command silently misbehaves. Using :normal! makes the behavior deterministic.
Example
Suppose the user has nnoremap w b (maps w to go backward). Then:
:g/function/normal w " moves BACKWARD (follows user mapping)
:g/function/normal! w " moves forward one word (built-in Vim w)
In a function or autocmd meant to be shared or reused, always prefer :normal!:
function! TrimTrailingWhitespace()
:%s/\s\+$//e
:normal! ``
endfunction
Tips
:normal!is the idiomatic choice in plugins and scripts for exactly this reason- You can range it:
:%normal! >>indents every line using built-in>> - Combining with
:gis common::g/^$/normal! ddto delete blank lines using the realdd q:history is per-mode;:normal!commands don't go into the normal-mode undo/redo macro history