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

Re: Read from command output broken on windows

Expand Messages
  • Ben Fritz
    ... This is an old-style workaround for the bad defaults. Adding an extra at the beginning and end of the string and allowing cmd.exe to strip them off is
    Message 1 of 12 , Sep 11, 2013
    • 0 Attachment
      On Wednesday, September 11, 2013 10:13:17 AM UTC-5, Jan Stocker wrote:
      >
      >
      >
      > So how would you run a valid cmd.exe line
      >
      >
      >
      > "c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces"
      >
      >

      This is exactly the situation that the changes were designed for! For me the defaults work. I just now launched vim with "gvim -N -u NONE -i NONE" and ran this command, getting the expected diff output in a command window:

      :!"C:\Program Files (x86)\vim\vim74\diff.exe" "C:\Users\btfritz\AppData\Local\Temp\file 1.txt" "C:\Users\btfritz\AppData\Local\Temp\file 2.txt"

      >
      > from a script rather than
      >
      >
      >
      > exe 'r!cmd.exe /c ""c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces""'
      >
      >

      This is an old-style workaround for the bad defaults. Adding an extra " at the beginning and end of the string and allowing cmd.exe to strip them off is how this works.

      The problem is now you're escaping the special characters only once, but you're running cmd.exe twice. So you need to escape them manually to prevent the implicitly called cmd.exe from seeing unescaped special characters outside of matching quotes. Or, just call the program directly instead of wrapping it with cmd.exe.

      I.e. you can use my command above, or this variant:

      :!cmd /c ""C:\Program Files ^(x86^)\vim\vim74\diff.exe" "C:\Users\btfritz\AppData\Local\Temp\file 1.txt" "C:\Users\btfritz\AppData\Local\Temp\file 2.txt""

      >
      > which does not work with default settings under 7.4 (I patched it today using short file names, but that is no solution)?
      >
      >

      Patch it instead to use the full command.

      >
      > And what to do to run this for 7.3 (some version before the patch) AND 7.4?
      >

      In this specific case, you can check the version and patchlevel using (v:version<7.3 || v:version==7.3 && !has('patch450')) and set 'shellxquote' to a single " character if true. This uses Vim to automatically surround the entire thing in an extra pair of quotes like the existing code does manually. This would have been the correct fix in the first place instead of this workaround.

      Naturally you'll need to save and restore shellxquote around this. And only do this on Windows.

      Something like (untested):

      if has('win32') && (v:version<7.3 || v:version==7.3 && !has('patch450')) && &shell=~cmd
      let s:shxq_sav = &shellxquote
      set shellxquote="
      endif
      !"c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces"
      if exists('s:shxq_sav')
      let &shellxquote = s:shxq_sav
      unlet s:shxq_sav
      endif

      --
      --
      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/groups/opt_out.
    • Tony Mechelynck
      ... Space, backslash and double-quote need backslash-escaping when used in a ... Use set shellxquote= to set shellxquote to just a double-quote character.
      Message 2 of 12 , Sep 11, 2013
      • 0 Attachment
        On 11/09/13 19:32, Ben Fritz wrote:
        > On Wednesday, September 11, 2013 10:13:17 AM UTC-5, Jan Stocker wrote:
        >>
        >>
        >>
        >> So how would you run a valid cmd.exe line
        >>
        >>
        >>
        >> "c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces"
        >>
        >>
        >
        > This is exactly the situation that the changes were designed for! For me the defaults work. I just now launched vim with "gvim -N -u NONE -i NONE" and ran this command, getting the expected diff output in a command window:
        >
        > :!"C:\Program Files (x86)\vim\vim74\diff.exe" "C:\Users\btfritz\AppData\Local\Temp\file 1.txt" "C:\Users\btfritz\AppData\Local\Temp\file 2.txt"
        >
        >>
        >> from a script rather than
        >>
        >>
        >>
        >> exe 'r!cmd.exe /c ""c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces""'
        >>
        >>
        >
        > This is an old-style workaround for the bad defaults. Adding an extra " at the beginning and end of the string and allowing cmd.exe to strip them off is how this works.
        >
        > The problem is now you're escaping the special characters only once, but you're running cmd.exe twice. So you need to escape them manually to prevent the implicitly called cmd.exe from seeing unescaped special characters outside of matching quotes. Or, just call the program directly instead of wrapping it with cmd.exe.
        >
        > I.e. you can use my command above, or this variant:
        >
        > :!cmd /c ""C:\Program Files ^(x86^)\vim\vim74\diff.exe" "C:\Users\btfritz\AppData\Local\Temp\file 1.txt" "C:\Users\btfritz\AppData\Local\Temp\file 2.txt""
        >
        >>
        >> which does not work with default settings under 7.4 (I patched it today using short file names, but that is no solution)?
        >>
        >>
        >
        > Patch it instead to use the full command.
        >
        >>
        >> And what to do to run this for 7.3 (some version before the patch) AND 7.4?
        >>
        >
        > In this specific case, you can check the version and patchlevel using (v:version<7.3 || v:version==7.3 && !has('patch450')) and set 'shellxquote' to a single " character if true. This uses Vim to automatically surround the entire thing in an extra pair of quotes like the existing code does manually. This would have been the correct fix in the first place instead of this workaround.
        >
        > Naturally you'll need to save and restore shellxquote around this. And only do this on Windows.
        >
        > Something like (untested):
        >
        > if has('win32') && (v:version<7.3 || v:version==7.3 && !has('patch450')) && &shell=~cmd
        > let s:shxq_sav = &shellxquote
        > set shellxquote="

        Space, backslash and double-quote need backslash-escaping when used in a
        :set statement, see :help option-backslash

        Use
        set shellxquote=\"
        to set 'shellxquote' to just a double-quote character. Or else, use
        let &shellxquote = '"'

        > endif
        > !"c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces"
        > if exists('s:shxq_sav')
        > let &shellxquote = s:shxq_sav
        > unlet s:shxq_sav
        > endif
        >

        Best regards,
        Tony.
        --
        Only a mediocre person is always at his best.
        -- Laurence Peter

        --
        --
        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/groups/opt_out.
      • Jan Stocker
        ... Thank you all for your help. Of course you have double escape stuff when using cmd.exe twice, I missed that. By the way, here is a code snippet tested on
        Message 3 of 12 , Sep 14, 2013
        • 0 Attachment
          >> Something like (untested):
          >>
          >> if has('win32') && (v:version<7.3 || v:version==7.3 && !has('patch450')) && &shell=~cmd
          >> let s:shxq_sav = &shellxquote
          >> set shellxquote="
          >
          > Space, backslash and double-quote need backslash-escaping when used in a :set statement, see :help option-backslash
          >
          > Use
          > set shellxquote=\"
          > to set 'shellxquote' to just a double-quote character. Or else, use
          > let &shellxquote = '"'
          >
          >> endif
          >> !"c:\program files (x86)\xyz\xyz.exe" "arg1 with spaces" "arg 2 with spaces"
          >> if exists('s:shxq_sav')
          >> let &shellxquote = s:shxq_sav
          >> unlet s:shxq_sav
          >> endif
          >>

          Thank you all for your help. Of course you have double escape stuff when using cmd.exe twice, I missed that. By the way, here is a code snippet tested on Win32 based on your notes:

          if has('win32') && (v:version<703 || (v:version==703 && !has('patch450'))) && &shell=~'cmd'
          let s:shxq_sav = &shellxquote
          set shellxquote=\"
          endif

          silent! exe 'noautocmd r!'.a:cmdline

          if exists('s:shxq_sav')
          let &shellxquote = s:shxq_sav
          unlet s:shxq_sav
          endif

          Best regards,

          Jan

          --
          --
          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/groups/opt_out.
        Your message has been successfully submitted and would be delivered to recipients shortly.