When I am writing blog posts using reStructuredText, I have F5 bound to running an external script with current filename using %. The external script generates temporary file with template, which I can preview in browser with. The post title is extracted from the filename.
Inevitably, characters like \' or ! are used sometimes. If you have used shell long enough, you will know those characters may cause issues if they are not quoted or escaped correctly.
Since I am just a normal Vim user, not really have much knowledge and experience of coding for Vim configuration. But this time, I managed to put together stuff to get away from escaping issue.
My original keybinding is as the following:
map <F5> <ESC>:w<CR>:!gen-blog-rst.sh '%'<CR>
It saves the file, then run the gen-blog-rst.sh script. As you can see \'%\' definitely will have issues with \' character. I found out there is a Vim function shellescape() which does what I expect:
:echo shellescape("\"blah\" 'foorbar' blah!")
" outputs the following string
'"blah" '\''foorbar'\'' blah!'
You can safely pass to :!some_command as an argument. It will be like running (my default shell is Bash):
bash -c some_command '"blah" '\''foorbar'\'' blah!'
This some_command will get that long word from $1.
The problem is when using :!{cmd}, I can not put anything function in it, it is basically a plain string be passed to your default shell. I dont know if Vim has something like Command Substitution in Bash to work in string, if it does, let me know.
The solution I found for this part is to use :exec[ute] to wrap it up:
:exec '!gen-blog-rst.sh ' . shellescape(%)
So, the final map is:
map <F5> <ESC>:w<CR>:exec '!gen-blog-rst.sh ' . shellescape(%)<CR>
Note that % is used for the function, instead of just %. I used this to update my vimrc.