Refactor to use *WriteCmd/*ReadCmd autocommands.
With this change, we're able to properly handle errors from shell commands. This means no more overwriting the original file when an incorrect password is entered or some other similar scenario. Also, move the handling of entering recipients to gpg itself instead of mimicking that in Vim itself. Signed-off-by: James Vega <vega.james@gmail.com>
This commit is contained in:
parent
a8838d0e86
commit
bf67f5561a
150
plugin/gnupg.vim
150
plugin/gnupg.vim
@ -127,6 +127,7 @@ if (exists("g:loaded_gnupg") || &cp || exists("#BufReadPre#*.\(gpg\|asc\|pgp\)")
|
|||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
let g:loaded_gnupg = "$Revision$"
|
let g:loaded_gnupg = "$Revision$"
|
||||||
|
let s:GPGInitRun = 0
|
||||||
|
|
||||||
" check for correct vim version {{{2
|
" check for correct vim version {{{2
|
||||||
if (v:version < 700)
|
if (v:version < 700)
|
||||||
@ -143,19 +144,14 @@ endif
|
|||||||
augroup GnuPG
|
augroup GnuPG
|
||||||
autocmd!
|
autocmd!
|
||||||
|
|
||||||
" initialize the internal variables
|
|
||||||
autocmd BufNewFile,BufReadPre,FileReadPre *.\(gpg\|asc\|pgp\) call s:GPGInit()
|
|
||||||
" force the user to edit the recipient list if he opens a new file and public
|
|
||||||
" keys are preferred
|
|
||||||
autocmd BufNewFile *.\(gpg\|asc\|pgp\) if (exists("g:GPGPreferSymmetric") && g:GPGPreferSymmetric == 0) | call s:GPGEditRecipients() | endif
|
|
||||||
" do the decryption
|
" do the decryption
|
||||||
autocmd BufReadPost,FileReadPost *.\(gpg\|asc\|pgp\) call s:GPGDecrypt()
|
autocmd BufReadCmd,FileReadCmd *.\(gpg\|asc\|pgp\) call s:GPGInit()
|
||||||
|
autocmd BufReadCmd,FileReadCmd *.\(gpg\|asc\|pgp\) call s:GPGDecrypt()
|
||||||
|
autocmd BufReadCmd *.\(gpg\|asc\|pgp\) call s:GPGBufReadPost()
|
||||||
|
|
||||||
" convert all text to encrypted text before writing
|
" convert all text to encrypted text before writing
|
||||||
autocmd BufWritePre,FileWritePre *.\(gpg\|asc\|pgp\) call s:GPGEncrypt()
|
autocmd BufWriteCmd,FileWriteCmd *.\(gpg\|asc\|pgp\) call s:GPGInit()
|
||||||
" undo the encryption so we are back in the normal text, directly
|
autocmd BufWriteCmd,FileWriteCmd *.\(gpg\|asc\|pgp\) call s:GPGEncrypt()
|
||||||
" after the file has been written.
|
|
||||||
autocmd BufWritePost,FileWritePost *.\(gpg\|asc\|pgp\) call s:GPGEncryptPost()
|
|
||||||
|
|
||||||
" cleanup on leaving vim
|
" cleanup on leaving vim
|
||||||
autocmd VimLeave *.\(gpg\|asc\|pgp\) call s:GPGCleanup()
|
autocmd VimLeave *.\(gpg\|asc\|pgp\) call s:GPGCleanup()
|
||||||
@ -178,6 +174,9 @@ highlight default link GPGHighlightUnknownRecipient ErrorMsg
|
|||||||
" initialize the plugin
|
" initialize the plugin
|
||||||
"
|
"
|
||||||
function s:GPGInit()
|
function s:GPGInit()
|
||||||
|
if s:GPGInitRun
|
||||||
|
return
|
||||||
|
endif
|
||||||
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGInit()")
|
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGInit()")
|
||||||
|
|
||||||
" first make sure nothing is written to ~/.viminfo while editing
|
" first make sure nothing is written to ~/.viminfo while editing
|
||||||
@ -185,7 +184,7 @@ function s:GPGInit()
|
|||||||
set viminfo=
|
set viminfo=
|
||||||
|
|
||||||
" we don't want a swap file, as it writes unencrypted data to disk
|
" we don't want a swap file, as it writes unencrypted data to disk
|
||||||
set noswapfile
|
setl noswapfile
|
||||||
|
|
||||||
" check what gpg command to use
|
" check what gpg command to use
|
||||||
if (!exists("g:GPGExecutable"))
|
if (!exists("g:GPGExecutable"))
|
||||||
@ -296,6 +295,7 @@ function s:GPGInit()
|
|||||||
call s:GPGDebug(2, "hashing algorithms: " . s:GPGHash)
|
call s:GPGDebug(2, "hashing algorithms: " . s:GPGHash)
|
||||||
call s:GPGDebug(2, "compression algorithms: " . s:GPGCompress)
|
call s:GPGDebug(2, "compression algorithms: " . s:GPGCompress)
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGInit()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGInit()")
|
||||||
|
let s:GPGInitRun = 1
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Function: s:GPGCleanup() {{{2
|
" Function: s:GPGCleanup() {{{2
|
||||||
@ -319,11 +319,13 @@ endfunction
|
|||||||
function s:GPGDecrypt()
|
function s:GPGDecrypt()
|
||||||
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGDecrypt()")
|
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGDecrypt()")
|
||||||
|
|
||||||
" switch to binary mode to read the encrypted file
|
|
||||||
set bin
|
|
||||||
|
|
||||||
" get the filename of the current buffer
|
" get the filename of the current buffer
|
||||||
let filename = expand("%:p")
|
let filename = expand("<afile>:p")
|
||||||
|
|
||||||
|
" File doesn't exist yet, so force recipients
|
||||||
|
if empty(glob(filename))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
" clear GPGEncrypted, GPGRecipients and GPGOptions
|
" clear GPGEncrypted, GPGRecipients and GPGOptions
|
||||||
let b:GPGEncrypted = 0
|
let b:GPGEncrypted = 0
|
||||||
@ -391,7 +393,7 @@ function s:GPGDecrypt()
|
|||||||
echohl GPGWarning
|
echohl GPGWarning
|
||||||
echom "File is not encrypted, all GPG functions disabled!"
|
echom "File is not encrypted, all GPG functions disabled!"
|
||||||
echohl None
|
echohl None
|
||||||
set nobin
|
silent exe '.r ' . fnameescape(filename)
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()")
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
@ -406,7 +408,7 @@ function s:GPGDecrypt()
|
|||||||
" since even with the --quiet option passphrase typos will be reported,
|
" since even with the --quiet option passphrase typos will be reported,
|
||||||
" we must redirect stderr (using shell temporarily)
|
" we must redirect stderr (using shell temporarily)
|
||||||
call s:GPGDebug(1, "decrypting file")
|
call s:GPGDebug(1, "decrypting file")
|
||||||
let commandline = "'[,']!" . s:GPGCommand . " --quiet --decrypt " . s:stderrredirnull
|
let commandline = "r !" . s:GPGCommand . ' --quiet --decrypt ' . shellescape(filename, 1) . ' ' . s:stderrredirnull
|
||||||
call s:GPGDebug(1, "command: " . commandline)
|
call s:GPGDebug(1, "command: " . commandline)
|
||||||
let &shellredir = s:shellredir
|
let &shellredir = s:shellredir
|
||||||
let &shell = s:shell
|
let &shell = s:shell
|
||||||
@ -414,29 +416,29 @@ function s:GPGDecrypt()
|
|||||||
let &shellredir = s:shellredirsave
|
let &shellredir = s:shellredirsave
|
||||||
let &shell = s:shellsave
|
let &shell = s:shellsave
|
||||||
if (v:shell_error) " message could not be decrypted
|
if (v:shell_error) " message could not be decrypted
|
||||||
silent u
|
|
||||||
echohl GPGError
|
echohl GPGError
|
||||||
let blackhole = input("Message could not be decrypted! (Press ENTER)")
|
let blackhole = input("Message could not be decrypted! (Press ENTER)")
|
||||||
echohl None
|
echohl None
|
||||||
bwipeout
|
silent bwipeout!
|
||||||
set nobin
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()")
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" turn off binary mode
|
|
||||||
set nobin
|
|
||||||
|
|
||||||
" call the autocommand for the file minus .gpg$
|
|
||||||
execute ":doautocmd BufReadPost " . fnameescape(expand("%:r"))
|
|
||||||
call s:GPGDebug(2, "called autocommand for " . fnameescape(expand("%:r")))
|
|
||||||
|
|
||||||
" refresh screen
|
" refresh screen
|
||||||
redraw!
|
redraw!
|
||||||
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()")
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function s:GPGBufReadPost()
|
||||||
|
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGBufReadPost()")
|
||||||
|
silent 1delete
|
||||||
|
" call the autocommand for the file minus .gpg$
|
||||||
|
execute ':doautocmd BufReadPost ' . fnameescape(expand('<afile>:r'))
|
||||||
|
call s:GPGDebug(2, 'called autocommand for ' . fnameescape(expand('<afile>:r')))
|
||||||
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGBufReadPost()")
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Function: s:GPGEncrypt() {{{2
|
" Function: s:GPGEncrypt() {{{2
|
||||||
"
|
"
|
||||||
" encrypts the buffer to all previous recipients
|
" encrypts the buffer to all previous recipients
|
||||||
@ -444,10 +446,6 @@ endfunction
|
|||||||
function s:GPGEncrypt()
|
function s:GPGEncrypt()
|
||||||
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEncrypt()")
|
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEncrypt()")
|
||||||
|
|
||||||
" save window view
|
|
||||||
let s:GPGWindowView = winsaveview()
|
|
||||||
call s:GPGDebug(2, "saved window view " . string(s:GPGWindowView))
|
|
||||||
|
|
||||||
" store encoding and switch to a safe one
|
" store encoding and switch to a safe one
|
||||||
if (&fileencoding != &encoding)
|
if (&fileencoding != &encoding)
|
||||||
let s:GPGEncoding = &encoding
|
let s:GPGEncoding = &encoding
|
||||||
@ -458,13 +456,10 @@ function s:GPGEncrypt()
|
|||||||
call s:GPGDebug(2, "encoding and fileencoding are the same (\"" . &encoding . "\"), not switching")
|
call s:GPGDebug(2, "encoding and fileencoding are the same (\"" . &encoding . "\"), not switching")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" switch buffer to binary mode
|
|
||||||
set bin
|
|
||||||
|
|
||||||
" guard for unencrypted files
|
" guard for unencrypted files
|
||||||
if (!exists("b:GPGEncrypted") || b:GPGEncrypted == 0)
|
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
|
||||||
echohl GPGError
|
echohl GPGError
|
||||||
let blackhole = input("Message could not be encrypted! File might be empty! (Press ENTER)")
|
let blackhole = input("Message could not be encrypted! (Press ENTER)")
|
||||||
echohl None
|
echohl None
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()")
|
||||||
return
|
return
|
||||||
@ -494,6 +489,10 @@ function s:GPGEncrypt()
|
|||||||
let options = options . " --" . option . " "
|
let options = options . " --" . option . " "
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
if (!exists('b:GPGRecipients'))
|
||||||
|
let b:GPGRecipients = []
|
||||||
|
endif
|
||||||
|
|
||||||
" check here again if all recipients are available in the keyring
|
" check here again if all recipients are available in the keyring
|
||||||
let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients)
|
let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients)
|
||||||
|
|
||||||
@ -513,57 +512,17 @@ function s:GPGEncrypt()
|
|||||||
for gpgid in recipients
|
for gpgid in recipients
|
||||||
let options = options . " -r " . gpgid
|
let options = options . " -r " . gpgid
|
||||||
endfor
|
endfor
|
||||||
else
|
|
||||||
if (match(b:GPGOptions, "encrypt") >= 0)
|
|
||||||
echohl GPGError
|
|
||||||
echom "There are no recipients!!"
|
|
||||||
echom "Please use GPGEditRecipients to correct!!"
|
|
||||||
echo
|
|
||||||
echohl None
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" encrypt the buffer
|
" encrypt the buffer
|
||||||
let commandline = "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . " " . s:stderrredirnull
|
let destfile = tempname()
|
||||||
|
let commandline = "'[,']w !" . s:GPGCommand . ' --quiet --no-encrypt-to ' . options . '>' . shellescape(destfile, 1) . ' ' . s:stderrredirnull
|
||||||
call s:GPGDebug(1, "command: " . commandline)
|
call s:GPGDebug(1, "command: " . commandline)
|
||||||
let &shellredir = s:shellredir
|
let &shellredir = s:shellredir
|
||||||
let &shell = s:shell
|
let &shell = s:shell
|
||||||
silent execute commandline
|
silent execute commandline
|
||||||
let &shellredir = s:shellredirsave
|
let &shellredir = s:shellredirsave
|
||||||
let &shell = s:shellsave
|
let &shell = s:shellsave
|
||||||
if (v:shell_error) " message could not be encrypted
|
|
||||||
" delete content of the buffer to be sure no data is written unencrypted
|
|
||||||
" content will be recovered in GPGEncryptPost()
|
|
||||||
silent normal! 1GdG
|
|
||||||
|
|
||||||
echohl GPGError
|
|
||||||
let blackhole = input("Message could not be encrypted! File might be empty! (Press ENTER)")
|
|
||||||
echohl None
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()")
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()")
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Function: s:GPGEncryptPost() {{{2
|
|
||||||
"
|
|
||||||
" undo changes don by encrypt, after writing
|
|
||||||
"
|
|
||||||
function s:GPGEncryptPost()
|
|
||||||
call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEncryptPost()")
|
|
||||||
|
|
||||||
" guard for unencrypted files
|
|
||||||
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncryptPost()")
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
" undo encryption of buffer content
|
|
||||||
silent u
|
|
||||||
|
|
||||||
" switch back from binary mode
|
|
||||||
set nobin
|
|
||||||
|
|
||||||
" restore encoding
|
" restore encoding
|
||||||
if (s:GPGEncoding != "")
|
if (s:GPGEncoding != "")
|
||||||
@ -571,14 +530,19 @@ function s:GPGEncryptPost()
|
|||||||
call s:GPGDebug(2, "restored encoding \"" . &encoding . "\"")
|
call s:GPGDebug(2, "restored encoding \"" . &encoding . "\"")
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" restore window view
|
if (v:shell_error) " message could not be encrypted
|
||||||
call winrestview(s:GPGWindowView)
|
" Command failed, so clean up the tempfile
|
||||||
call s:GPGDebug(2, "restored window view" . string(s:GPGWindowView))
|
call delete(destfile)
|
||||||
|
echohl GPGError
|
||||||
|
let blackhole = input("Message could not be encrypted! (Press ENTER)")
|
||||||
|
echohl None
|
||||||
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
" refresh screen
|
call rename(destfile, expand('<afile>'))
|
||||||
redraw!
|
setl nomodified
|
||||||
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()")
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncryptPost()")
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Function: s:GPGViewRecipients() {{{2
|
" Function: s:GPGViewRecipients() {{{2
|
||||||
@ -667,7 +631,7 @@ function s:GPGEditRecipients()
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
" empty the buffer
|
" empty the buffer
|
||||||
silent normal! 1GdG
|
silent %delete
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Mark the buffer as a scratch buffer
|
" Mark the buffer as a scratch buffer
|
||||||
@ -732,10 +696,10 @@ function s:GPGEditRecipients()
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
" delete the empty first line
|
" delete the empty first line
|
||||||
silent normal! 1Gdd
|
silent 1delete
|
||||||
|
|
||||||
" jump to the first recipient
|
" jump to the first recipient
|
||||||
silent normal! G
|
silent $
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -814,7 +778,7 @@ function s:GPGFinishRecipientsBuffer()
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
" reset modified flag
|
" reset modified flag
|
||||||
set nomodified
|
setl nomodified
|
||||||
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishRecipientsBuffer()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishRecipientsBuffer()")
|
||||||
endfunction
|
endfunction
|
||||||
@ -889,7 +853,7 @@ function s:GPGEditOptions()
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
" empty the buffer
|
" empty the buffer
|
||||||
silent normal! 1GdG
|
silent %delete
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Mark the buffer as a scratch buffer
|
" Mark the buffer as a scratch buffer
|
||||||
@ -921,10 +885,10 @@ function s:GPGEditOptions()
|
|||||||
endfor
|
endfor
|
||||||
|
|
||||||
" delete the empty first line
|
" delete the empty first line
|
||||||
silent normal! 1Gdd
|
silent 1delete
|
||||||
|
|
||||||
" jump to the first option
|
" jump to the first option
|
||||||
silent normal! G
|
silent $
|
||||||
|
|
||||||
" define highlight
|
" define highlight
|
||||||
if (has("syntax") && exists("g:syntax_on"))
|
if (has("syntax") && exists("g:syntax_on"))
|
||||||
@ -987,7 +951,7 @@ function s:GPGFinishOptionsBuffer()
|
|||||||
call setbufvar(b:GPGCorrespondingTo, "&mod", 1)
|
call setbufvar(b:GPGCorrespondingTo, "&mod", 1)
|
||||||
|
|
||||||
" reset modified flag
|
" reset modified flag
|
||||||
set nomodified
|
setl nomodified
|
||||||
|
|
||||||
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishOptionsBuffer()")
|
call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishOptionsBuffer()")
|
||||||
endfunction
|
endfunction
|
||||||
|
Loading…
Reference in New Issue
Block a user