Loading ...
Sorry, an error occurred while loading the content.

75544Re: Incorrect expansion of %? (with patch)

Expand Messages
  • Gary Johnson
    Mar 10, 2014
    • 0 Attachment
      On 2014-03-08, Bram Moolenaar wrote:
      > Gary Johnson wrote:
      >
      > > On 2014-03-04, Gary Johnson wrote:
      > > > On 2014-03-04, Christian Brabandt wrote:
      > > > > Am 2014-03-04 08:15, schrieb Gary Johnson:
      > > > > >There is a difference between the expansion of % and Ctrl-R % on the
      > > > > >command line.
      > > > > >
      > > > > >I use Dropbox to keep a number of my configuration files, including
      > > > > >my ~/.vim directory, synchronized between various machines running
      > > > > >Linux and Windows.
      > > > > >
      > > > > >Today I discovered this file in the ~/Dropbox/vimfiles of a machine
      > > > > >named toucan which is running Fedora 14:
      > > > > >
      > > > > > filetype (toucan's conflicted copy 2014-03-01).vim
      > > > > >
      > > > > >Using a GUI file manager, I opened this file with gvim. I made some
      > > > > >changes to it, then tried comparing the changed buffer with the
      > > > > >copy on disk with this command which I have used for years:
      > > > > >
      > > > > > :w !diff "%" -
      > > > > >
      > > > > >The result surprised me.
      > > > > >
      > > > > > diff: Dropbox/vimfiles/filetype \(toucan's conflicted copy
      > > > > >2014-03-01\).vim: No such file or directory
      > > > >
      > > > > That indeed looks wrong. Interestingly, it seems to work for me, when
      > > > > escaping the quote, like this:
      > > > >
      > > > > :w !cmd \"%\" -
      > > > >
      > > > > (note sure, why this works).
      > > > >
      > > > > For the most recent versions, I think :w !cmd %:S - should also work.
      > > >
      > > > I observed the problem on Linux, not Windows, so cmd is not
      > > > involved. Vim's expansion of % may differ between Linux and
      > > > Windows.
      > >
      > > Attached is a patch that fixes this on Linux.
      > >
      > > I think the original code was a well-intentioned but incorrect
      > > attempt to quote characters in the expansion of % that are special
      > > to the shell. The problem is that the quoting is inconsistent. If
      > > one is going to quote a file name so that % expands usefully in a
      > > shell command such as
      > >
      > > :!cat %
      > >
      > > then all characters special to the shell must be quoted. The
      > > current Vim code quotes the characters "!&;()<>" but not space.
      > > Consequently, any spaces in the file name are seen by the shell as
      > > separators.
      > >
      > > If one attempts to fix the space problem by quoting the file name as
      > >
      > > :!cat "%"
      > >
      > > and the file name contains any of the characters "!&;()<>", then the
      > > backslashes used by Vim to quote those characters appear to the
      > > shell as literal backslashes.
      > >
      > > Since users are used to placing file names that may contain special
      > > characters withing quotes, I think it would be least confusing for
      > > Vim not to try to help with additional quoting. Therefore this
      > > patch removes this extra quoting. This also preserves the current
      > > behavior in the most common case of file names containing spaces.
      > > It is much less common for file names to include any of "!&;()<>",
      > > and with this bug, there is no way for the user to use % in a shell
      > > command if % expands to a name containing any of those characters
      > > and a space.
      > >
      > > The patch is based on Vim 7.4.135.
      >
      > Thanks.
      >
      > Yeah, it should either escape the spaces as well, so that % can be used
      > without the quotes, or escape nothing, so that "%" works.
      >
      > Doesn't $ need escaping even inside ""? But not inside ''. Hmm,
      > perhaps instead of a quick fix we can think of how to do this properly?

      I started investigating a more proper solution by reading more of
      the related code in Vim and the bash man page. This is more
      difficult than I thought it would be.

      Not escaping any characters in the expansion of % and requiring the
      user to double-quote the % in the command (e.g., "%") doesn't work
      if the file name contains the character " or the characters !$\
      depending on what they're followed by and whether history expansion
      is enabled.

      Not escaping any characters in the expansion of % and requiring the
      user to single-quote the % in the command (e.g., '%') doesn't work
      if the file name contains the character '.

      As I see it now, the only way to protect all the characters in the
      expansion of % so that it will be seen as the correct file name by
      the shell is to backslash-escape them and require the user to not
      try to quote the %.

      That is completely opposite to the solution proposed in my patch.
      The better solution seems to be to add the space character to the
      lists of characters to be escaped in the original Vim code. I think
      the characters ${} need to be added as well to protect against
      parameter and brace expansion and *[] to protect against pattern
      expansions.

      A user who doesn't want the backslash escaping of % can always do
      something like this:

      :exe '!command "'.expand('%').'"'

      I'll follow up with another patch after I've thought a little more
      about this. I guess I'll have to figure out how to write a test,
      too.

      Regards,
      Gary

      --
      --
      You received this message from the "vim_dev" maillist.
      Do not top-post! Type your reply below the text you are replying to.
      For more information, visit http://www.vim.org/maillist.php

      ---
      You received this message because you are subscribed to the Google Groups "vim_dev" group.
      To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
      For more options, visit https://groups.google.com/d/optout.
    • Show all 14 messages in this topic