How do I insert a shell-escaped current file path in a Vim command-line?
Answer
%:S
Explanation
When you build shell commands from Vim, file paths with spaces or special characters can break the command unless properly escaped. The %:S filename modifier expands the current file path and applies shell escaping for you. This is especially useful in :! commands, :make, and custom mappings that call external tools.
How it works
%means "current buffer file name" in command-line expansions:Sapplies shell escaping to that expanded path- You can combine modifiers, for example
%:p:Sfor absolute path then escaped
Because escaping rules vary by shell, relying on Vim's modifier is safer than manually adding quotes each time. It also avoids edge cases when paths include parentheses, spaces, or # characters.
Example
Imagine the current file is:
/home/finn/projects/my app/src/main file.ts
In command-line mode:
:!rg TODO %:S
Vim expands %:S into a shell-safe version of the file path, so rg receives the right argument even with spaces.
Tips
- Use
%:p:Swhen tools require absolute paths #(alternate file) also supports modifiers:#:S- For non-shell contexts inside Vimscript, use
fnameescape()instead of shell-style escaping