Support using vim-gnupg from cygwin with Gpg4win

Gpg4win expects native Windows paths even when it's being run from a
cygwin environment.  In order to satisfy that, update `s:shellescape` to
know whether it should convert the paths to native Windows paths using
`cygpath -am`.

In order to detect whether cygpath should be invoked, look for the
combination of `has('win32unix')` being true and `gpg --version`
reporting a Windows style path for gpg's home directory.

Closes jamessan/vim-gnupg#62

Signed-off-by: James McCoy <jamessan@jamessan.com>
This commit is contained in:
James McCoy 2016-12-05 08:36:59 -05:00
parent 5103285d4d
commit 9d600d73fa
No known key found for this signature in database
GPG Key ID: DFE691AE331BA3DB

View File

@ -220,24 +220,35 @@ highlight default link GPGHighlightUnknownRecipient ErrorMsg
" Section: Functions {{{1
" Function: s:shellescape(s[, special]) {{{2
" Function: s:shellescape(s[, dict]) {{{2
"
" Calls shellescape(), also taking into account 'shellslash'
" when on Windows and using $COMSPEC as the shell.
"
" Recognized keys are:
" special - Passed through as special argument for Vim's shellescape()
" cygpath - When true and s:useCygpath is true, adjust the path to work with
" Gpg4win from cygwin
"
" Returns: shellescaped string
"
function s:shellescape(s, ...)
let special = a:0 ? a:1 : 0
let opts = a:0 ? a:1 : {}
let special = get(opts, 'special', 0)
let cygpath = get(opts, 'cygpath', 0)
let s = a:s
if cygpath && s:useCygpath
let s = matchstr(system('cygpath -am '.shellescape(s)), '[^\x0a\x0d]*')
endif
if exists('+shellslash') && &shell == $COMSPEC
let ssl = &shellslash
set noshellslash
let escaped = shellescape(a:s, special)
let escaped = shellescape(s, special)
let &shellslash = ssl
else
let escaped = shellescape(a:s, special)
let escaped = shellescape(s, special)
endif
return escaped
@ -387,6 +398,13 @@ function s:GPGInit(bufread)
let s:GPGCipher = substitute(output, ".*Cipher: \\(.\\{-}\\)\n.*", "\\1", "")
let s:GPGHash = substitute(output, ".*Hash: \\(.\\{-}\\)\n.*", "\\1", "")
let s:GPGCompress = substitute(output, ".*Compress.\\{-}: \\(.\\{-}\\)\n.*", "\\1", "")
let s:GPGHome = matchstr(output, '.*Home: \zs.\{-}\ze\r\=\n')
let s:useCygpath = 0
if has('win32unix') && s:GPGHome =~ '\a:[/\\]'
call s:GPGDebug(1, 'Enabling use of cygpath')
let s:useCygpath = 1
endif
" determine if gnupg can use the gpg-agent
if (str2float(gpgversion) >= 2.1 || (exists("$GPG_AGENT_INFO") && g:GPGUseAgent == 1))
@ -476,7 +494,7 @@ function s:GPGDecrypt(bufread)
" find the recipients of the file
let cmd = { 'level': 3 }
let cmd.args = '--verbose --decrypt --list-only --dry-run --no-use-agent --logger-fd 1 ' . s:shellescape(filename)
let cmd.args = '--verbose --decrypt --list-only --dry-run --no-use-agent --logger-fd 1 ' . s:shellescape(filename, { 'cygpath': 1 })
let output = s:GPGSystem(cmd)
" Suppress the "N more lines" message when editing a file, not when reading
@ -568,7 +586,7 @@ function s:GPGDecrypt(bufread)
" we must redirect stderr (using shell temporarily)
call s:GPGDebug(1, "decrypting file")
let cmd = { 'level': 1, 'ex': silent . 'read ++edit !' }
let cmd.args = '--quiet --decrypt ' . s:shellescape(filename, 1)
let cmd.args = '--quiet --decrypt ' . s:shellescape(filename, { 'special': 1, 'cygpath': 1 })
call s:GPGExecute(cmd)
if (v:shell_error) " message could not be decrypted
@ -710,7 +728,7 @@ function s:GPGEncrypt()
let destfile = tempname()
let cmd = { 'level': 1, 'ex': "'[,']write !" }
let cmd.args = '--quiet --no-encrypt-to ' . options
let cmd.redirect = '>' . s:shellescape(destfile, 1)
let cmd.redirect = '>' . s:shellescape(destfile, { 'special': 1, 'cygpath': 1 })
silent call s:GPGExecute(cmd)
if (v:shell_error) " message could not be encrypted
@ -1349,7 +1367,7 @@ endfunction
function s:GPGSystem(dict)
let commandline = s:GPGCommand
if (!empty(g:GPGHomedir))
let commandline .= ' --homedir ' . s:shellescape(g:GPGHomedir)
let commandline .= ' --homedir ' . s:shellescape(g:GPGHomedir, { 'cygpath': 1 })
endif
let commandline .= ' ' . a:dict.args
let commandline .= ' ' . s:stderrredirnull
@ -1376,7 +1394,7 @@ endfunction
function s:GPGExecute(dict)
let commandline = printf('%s%s', a:dict.ex, s:GPGCommand)
if (!empty(g:GPGHomedir))
let commandline .= ' --homedir ' . s:shellescape(g:GPGHomedir, 1)
let commandline .= ' --homedir ' . s:shellescape(g:GPGHomedir, { 'special': 1, 'cygpath': 1 })
endif
let commandline .= ' ' . a:dict.args
if (has_key(a:dict, 'redirect'))