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

Re: Help with unwanted shell character expansion

Expand Messages
  • Bob Hiestand
    ... Thanks, Tony. I should provide context for my request. For my cvscommand plugin, which opens new buffers containing the results of CVS operations
    Message 1 of 9 , Aug 1, 2006
    • 0 Attachment
      On 7/31/06, A.J.Mechelynck <antoine.mechelynck@...> wrote:
      > Bob Hiestand wrote:
      > > Question one:
      > >
      > > Is there a way to achieve execution of system commands without using
      > > the shell? Here I'm thinking (for example) of, in perl, the
      > > difference between using a single argument to exec() and using
      > > multiple arguments. In the first version, shell characters are
      > > expanded, in the second, they are not.
      > >
      > > If there is no such functionality currently, is this a planned
      > > feature? I believe that such a feature would make writing portable
      > > plugins easier.
      >
      > AFAIK, the only way to execute an external program from Vim with no
      > shell wrapping is to set the 'shell' option itself to the program name.
      > There may be drawbacks and pitfalls to that approach, though.
      >
      > >
      > > Question two:
      > >
      > > Is there a way to set the buffer name without the name being subject
      > > to shell metacharacter expansion? As far as I know, only :edit,
      > > :split, :new, :write, and :file allow setting the buffer name, and
      > > those all apply shell expansion. I know that characters can be
      > > escaped, but that involved knowledge of which characters are
      > > significant on each platform and again leads to unportable code (or
      > > highly complex code that attempts to be portable by taking each system
      > > into account). I would like a function to set the buffer name
      > > (potentially for a buffer specified by number) or for the '%' register
      > > to be writable.
      > >
      > > Thank you,
      > >
      > > bob
      > >
      > >
      >
      > A buffer name is usually a (potential) file name. Which characters are
      > allowed in a filename is system-dependent. On Dos and on 16-bit Windows,
      > only 8+3 names are allowed (with no embedded spaces). On Unix, case is
      > usually significant while on Windows it usually isn't. And so on.
      >
      > Also, Windows versions of Vim expand wildcards, while Unix versions
      > leave the expansion (except for ** which is a Vim-specific extension) to
      > the shell.
      >
      > The buffer name can also be set by ":saveas", ":view", ":sview"... I'm
      > not sure I got them all. I expect all of these to also expand, for
      > instance, environment variables. ":saveas" is (IIUC) equivalent to
      > altering the current buffer's name then writing it under the new name.
      > If the new name already exists, ":saveas filename" will fail but
      > ":saveas! filename" will succeed (unless of course there is a further
      > write-error, such as a "disk full" condition).
      >
      > IIUC, all Vim's internal file-related commands accept a "unix-like"
      > filename syntax, and Vim translates it if necessary to the OS's syntax:
      > e.g., when Vim for Windows receives the command ":view
      > $VIMRUNTIME/vimrc_example.vim" (with an environment variable and using a
      > forward slash as separator) the string it passes to the Windows "file
      > open" function will be something like "C:\Program
      > Files\vim\vim70\vimrc_example.vim" (without the quotes and with a
      > terminating null byte IIUC, but also with the environment variable
      > resolved and, most important, with backslashes as separators).
      > Similarly, in Vim for Windows embedded spaces are backslash-escaped (as
      > in Unix), even though the Windows syntax is not to use any embedded
      > escaping but to wrap the whole name in double quotes.
      >
      > If you want to build "portable" names for newly-created files, then
      >
      > (assuming you can disregard pre-Win32 Dos-like systems) I suggest
      > limiting yourself to lowercase letters, digits, underscore and period.
      > Some systems allow more than that (and some OS versions accept Unicode
      > non-ASCII characters in filenames) but I believe that with [0-9a-z_.]
      > you can be fairly certain that your filename will be legal "almost
      > everywhere", and that different names will refer to different files.
      >
      >
      > Best regards,
      > Tony.
      >

      Thanks, Tony. I should provide context for my request. For my
      cvscommand plugin, which opens new buffers containing the results of
      CVS operations performed on the file associated with the current
      buffer, I need to be able to name the resulting scratch buffers.
      These buffers will be explicitly not associated with files.

      I used to have these as nameless files, and used the statusline to
      pull up custom variables set by the plugin to create a suitable
      display name (something like "[CVS log originalFileName]"). The
      problem with this solution is that the buffer list commands just show
      the nameless scratch buffers, of course, making navigation difficult.

      As an alternative, in the new version of the plugin, I explicitly name
      the buffers. However, that means that the original file name appears
      in the buffer name, and is subject to shell expansion.

      While it is indeed possible to do as Yakov suggests and try to escape
      the shell meta-characters, I've experienced some difficulty in making
      that work across multiple platforms consistently (primarily Linux,
      Windows (various flavors), Windows + cygwin (my personal terror)). I
      actually already use the escape command, and ran into issues when
      Windows interpreted the resulting escaped character as a backslash +
      original character. While the help mentions a work-around for this in
      the case of the '[' character, I frankly don't want to have to worry
      with this particular source of bugs.

      It occurred to me that, particularly for scratch buffers, it ought to
      be possible to explicitly set the name without regard for file system
      conventions.

      Thanks for the responses,

      Bob
    • Bob Hiestand
      As is too often the case, I didn t read enough documentation. I think this is not a well-known feature. ... Yes, by using backtick notation along with the =
      Message 2 of 9 , Aug 3, 2006
      • 0 Attachment
        As is too often the case, I didn't read enough documentation. I think
        this is not a well-known feature.

        On 7/31/06, Bob Hiestand <bob.hiestand@...> wrote:

        > Question two:
        >
        > Is there a way to set the buffer name without the name being subject
        > to shell metacharacter expansion? As far as I know, only :edit,
        > :split, :new, :write, and :file allow setting the buffer name, and
        > those all apply shell expansion. I know that characters can be
        > escaped, but that involved knowledge of which characters are
        > significant on each platform and again leads to unportable code (or
        > highly complex code that attempts to be portable by taking each system
        > into account). I would like a function to set the buffer name
        > (potentially for a buffer specified by number) or for the '%' register
        > to be writable.

        Yes, by using backtick notation along with the '=' expression prefix,
        non-expansion is possible.

        For example,

        :e `=unescapedFileName`

        Thanks all for the replies,

        Bob
      • Yakov Lerner
        ... Does this really work fo you ? First, many characters are interpreted specially inside `=...`, Those are (,),+,- and all vim ... E121: Undefined variable:
        Message 3 of 9 , Aug 3, 2006
        • 0 Attachment
          On 8/3/06, Bob Hiestand <bob.hiestand@...> wrote:
          > As is too often the case, I didn't read enough documentation. I think
          > this is not a well-known feature.
          >
          > On 7/31/06, Bob Hiestand <bob.hiestand@...> wrote:
          >
          > > Question two:
          > >
          > > Is there a way to set the buffer name without the name being subject
          > > to shell metacharacter expansion? As far as I know, only :edit,
          > > :split, :new, :write, and :file allow setting the buffer name, and
          > > those all apply shell expansion. I know that characters can be
          > > escaped, but that involved knowledge of which characters are
          > > significant on each platform and again leads to unportable code (or
          > > highly complex code that attempts to be portable by taking each system
          > > into account). I would like a function to set the buffer name
          > > (potentially for a buffer specified by number) or for the '%' register
          > > to be writable.
          >
          > Yes, by using backtick notation along with the '=' expression prefix,
          > non-expansion is possible.
          >
          > For example,
          >
          > :e `=unescapedFileName`

          Does this really work fo you ? First, many characters
          are interpreted specially inside `=...`, Those are (,),+,- and all vim
          operators (see val.txt). Second, if I try your examlpe, I get:

          :e `=unescapedFileName`
          E121: Undefined variable: unescapedFIleName
          "`=unescapedFileName`" [New File]
          And then filename is set to
          `=unescapedFileName`

          Note how filename includes backticks and equal sign.

          Or did you possibly mean :e `='unescapedFileName'` ?

          Yakov
        • Bob Hiestand
          ... Another way to do this appears to be using the bufnr function with the create optional parameter set. I have not extensively tested it, but it seems
          Message 4 of 9 , Aug 7, 2006
          • 0 Attachment
            On 8/3/06, Bob Hiestand <bob.hiestand@...> wrote:
            > On 8/3/06, Yakov Lerner <iler.ml@...> wrote:
            > > On 8/3/06, Bob Hiestand <bob.hiestand@...> wrote:
            > > > As is too often the case, I didn't read enough documentation. I think
            > > > this is not a well-known feature.
            > > >
            > > > On 7/31/06, Bob Hiestand <bob.hiestand@...> wrote:
            > > >
            > > > > Question two:
            > > > >
            > > > > Is there a way to set the buffer name without the name being subject
            > > > > to shell metacharacter expansion? As far as I know, only :edit,
            > > > > :split, :new, :write, and :file allow setting the buffer name, and
            > > > > those all apply shell expansion. I know that characters can be
            > > > > escaped, but that involved knowledge of which characters are
            > > > > significant on each platform and again leads to unportable code (or
            > > > > highly complex code that attempts to be portable by taking each system
            > > > > into account). I would like a function to set the buffer name
            > > > > (potentially for a buffer specified by number) or for the '%' register
            > > > > to be writable.
            > > >
            > > > Yes, by using backtick notation along with the '=' expression prefix,
            > > > non-expansion is possible.
            > > >
            > > > For example,
            > > >
            > > > :e `=unescapedFileName`
            > >
            > > Does this really work fo you ? First, many characters
            > > are interpreted specially inside `=...`, Those are (,),+,- and all vim
            > > operators (see val.txt). Second, if I try your examlpe, I get:
            > >
            > > :e `=unescapedFileName`
            > > E121: Undefined variable: unescapedFIleName
            > > "`=unescapedFileName`" [New File]
            > > And then filename is set to
            > > `=unescapedFileName`
            > >
            > > Note how filename includes backticks and equal sign.
            > >
            > > Or did you possibly mean :e `='unescapedFileName'` ?
            > >
            > > Yakov
            > >
            >
            > Sorry, to be clear, unescapedFileName is a variable.

            Another way to do this appears to be using the 'bufnr' function with
            the 'create' optional parameter set. I have not extensively tested
            it, but it seems to be a useful alternative.
          Your message has been successfully submitted and would be delivered to recipients shortly.