7

I have this mapping in my .vimrc

nnoremap <silent><leader>vlc :exe "!open -a vlc '".getline('.')."'"<CR>

It does work great with some files, but I'm getting error message with files that have single quote in it:

/Users/dude/Downloads/check/39min tpope's Vim Config and Plugins-MGmIJyTf8pg.mp4

The error message:

/bin/bash: -c: line 0: unexpected EOF while looking for matching `''

/bin/bash: -c: line 1: syntax error: unexpected end of file

shell returned 2

Press ENTER or type command to continue

1 Answer 1

6

Rather than add quotes yourself, use the shellescape() function, which should take care or all edge cases:

:nnoremap <silent><leader>vlc :exe "!open -a vlc " . shellescape(getline('.'))<CR>

Another way is to use the %:S filename modifier:

:echo fnamemodify("Hello 'world", '')
Hello 'world

:echo fnamemodify("Hello 'world", ':S')
'Hello '\''world'

:echo expand('%')
hello 'world

:echo expand('%:S')
'hello '\''world'

In this particular case shellescape() probably makes more sense, but :S is useful especially when you want to combine it with other filename modifiers.

4
  • Thank you very much for your awesome help. It does work perfectly ^^
    – whitesiroi
    Commented Aug 12, 2016 at 12:15
  • 3
    Don't you also need fnameescape()? Commented Aug 12, 2016 at 12:17
  • @SatoKatsura Thanks, I think you may be right and that this answer is wrong >_< No time to update it right now. Commented Aug 12, 2016 at 12:41
  • 1
    This is more involved than it looks. You'd think that fnameescape(shellescape(...)) does the trick, but it doesn't. On UNIX you need at least something like this: escape(fnameescape(shellescape(...)), '&()'), but of course that won't work on Windows (I don't know the answer for Windows). This has to do with the way :! is implemented, and is the reason why syntastic switched from makeprg and friends to system() and lgetexpr. I'd be surprised if you could find a solution that actually works everywhere, across all sets of characters. :)
    – lcd047
    Commented Aug 12, 2016 at 17:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.