3

In my previous question, I passed an argument into a Vimscript function and concatenated it into the command line. This works great, but when you pass a string that contains the # character, it balks with an error about the following:

E499: Empty file name for '%' or '#', only works with `:p:h`: read!<shellcmd>

The vimscript function looks like this:

function! GetJobLines(a:argA)

    " 1. Create a new buffer for the output
    enew

    " 2. Change directory to location of said script
    cd /home/leeand00/src

    execute "read!echo" shellescape(a:argA)

functionend

Running the command itself looks like this:

:call GetJobLines("C#")

Myself I thought that including shellescape() would have taken care of this, however this is not the case. I also tried adding \# to escape the # character, but that does not work either...

When I run the same command from the command line directly it does not cause an issue, and clearly this is a problem to be corrected in vimscript, I just don't know how.

1
  • A single backslash may not work with double-quoted strings. It really depends on how you're building your command to execute. Jan 4, 2017 at 16:53

2 Answers 2

4

The problem is that some characters are considered special by the Vim commandline. In your case, # refers to the alternate file name.

You can find the documentation with a full list at :help cmdline-special. This also includes the two possible ways to prevent this:

  • Prefix it with a backslash:

    :execute ":read !echo " . shellescape('C\#')
    
  • Use the fnameescape() function:

    :execute ":read !echo " . shellescape(fnameescape('C#'))
    
6

shellescape({string}[, {special}]) has an extra, optional argument {special} which exists exactly for this purpose.

When the {special} argument is present and it's a non-zero Number or a non-empty String (non-zero-arg), then special items such as "!", "%", and "<cword>" will be preceded by a backslash. This backslash will be removed again by the :! command.

Therefore, what you want to use is :execute ':read !echo' shellescape(a:argA, 1).

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.