How do I chain multiple ex commands together on one line in Vim?
Answer
:%s/foo/bar/g | %s/baz/qux/g | w
Explanation
The | (bar) character in Vim's command line acts as a command separator, allowing you to chain multiple ex commands together on a single line. This is powerful for creating complex workflows and is essential for advanced Vim scripting.
How it works
When Vim encounters | in the command line, it treats everything before it as one command and everything after it as another command. The commands execute sequentially from left to right. If one command fails, subsequent commands may still execute depending on the context.
Note that | does not pipe output like in a Unix shell. It is purely a command separator. Each command runs independently with its own context.
Some commands consume the | character as part of their own syntax. Notably, :! (shell command), :command, :map, and :autocmd all treat | as part of their arguments rather than as a separator. For these, you can use <bar> in mappings or use the execute command as a workaround.
Example
Perform multiple substitutions and save in one command:
:%s/foo/bar/g | %s/baz/qux/g | w
This is especially powerful with :g and in script contexts:
" Delete blank lines and trailing whitespace, then save
:g/^$/d | %s/\s\+$//e | w
" Open a new tab with a specific file and set options
:tabnew config.yaml | setlocal filetype=yaml | set expandtab
" Close all other windows and go to first line
:only | 1
" In a mapping, use <bar> since | is consumed by :map
:nnoremap <leader>c :%s/foo/bar/g<bar>w<CR>
When writing Vim functions, you can use | to place multiple statements on one line, though using separate lines is generally more readable. In autocommands, | separates the commands to execute when the event triggers, making it common to see chains like `autocmd BufWritePre * :%s/\s+$//e | normal! ``` for pre-save cleanup.