releasing gnupg.vim 1472

- support for symmetric encrypted files.
- detection of various encryption options.
- possibility to change gpg options using new commands GPGEditOptions and GPGViewOptions commands.
- support editing files with '.gpg', '.pgp' and '.asc' suffixes (tanks to Richard Bronosky).
- detection of unencrypted files.
- support for windows systems (thanks to Erik Remmelzwaal).
This commit is contained in:
Markus Braun 2006-12-15 13:09:40 -05:00 committed by James Vega
parent 14dab8f3d6
commit 31d69b326a

View File

@ -1,14 +1,15 @@
" Name: gnupg.vim " Name: gnupg.vim
" Version: $Id: gnupg.vim,v 1.27 2003/06/24 07:57:16 mb Exp $ " Version: $Id: gnupg.vim 1472 2006-12-15 13:09:40Z mbr $
" Author: Markus Braun <markus.braun@krawel.de> " Author: Markus Braun <markus.braun@krawel.de>
" Summary: Vim plugin for transparent editing of gpg encrypted files. " Summary: Vim plugin for transparent editing of gpg encrypted files.
" TODO enable signing " Licence: This program is free software; you can redistribute it and/or
" TODO GPGOptions for encrypting, signing, auto fetch .. " modify it under the terms of the GNU General Public License.
" See http://www.gnu.org/copyleft/gpl.txt
" Section: Documentation {{{1 " Section: Documentation {{{1
" Description: " Description:
" "
" This script implements transparent editing of gpg public/private-key " This script implements transparent editing of gpg encrypted files. The
" encrypted files. The filename must have a ".gpg" suffix. When opening such " filename must have a ".gpg", ".pgp" or ".asc" suffix. When opening such
" a file the content is decrypted, when opening a new file the script will " a file the content is decrypted, when opening a new file the script will
" ask for the recipients of the encrypted file. The file content will be " ask for the recipients of the encrypted file. The file content will be
" encrypted to all recipients before it is written. The script turns off " encrypted to all recipients before it is written. The script turns off
@ -24,78 +25,171 @@
" "
" :GPGEditRecipients " :GPGEditRecipients
" Opens a scratch buffer to change the list of recipients. Recipients that " Opens a scratch buffer to change the list of recipients. Recipients that
" are unknown (not in your public key) are highlighted and have a " are unknown (not in your public key) are highlighted and have
" prepended "!". Closing the buffer with :x or :bd makes the changes permanent. " a prepended "!". Closing the buffer makes the changes permanent.
" "
" :GPGViewRecipients " :GPGViewRecipients
" Prints the list of recipients. " Prints the list of recipients.
" "
" :GPGEditOptions
" Opens a scratch buffer to change the options for encryption (symmetric,
" asymmetric, signing). Closing the buffer makes the changes permanent.
" WARNING: There is no check of the entered options, so you need to know
" what you are doing.
"
" :GPGViewOptions
" Prints the list of options.
"
" Variables:
"
" g:GPGUseAgent
" If set to 0 a possible available gpg-agent won't be used. Defaults to 1.
"
" Credits: " Credits:
" Mathieu Clabaut for inspirations through his vimspell.vim script. " Mathieu Clabaut for inspirations through his vimspell.vim script.
" Richard Bronosky for patch to enable ".pgp" suffix.
" Erik Remmelzwaal for patch to enable windows support and patient beta
" testing.
"
" Section: Plugin header {{{1 " Section: Plugin header {{{1
if (exists("loaded_gnupg") || &cp || exists("#BufReadPre#*.gpg")) if (exists("loaded_gnupg") || &cp || exists("#BufReadPre#*.\(gpg\|asc\|pgp\)"))
finish finish
endi endi
let loaded_gnupg = 1 let loaded_gnupg = 1
" dettermine if gnupg can use the gpg-agent
if (exists("$GPG_AGENT_INFO"))
let s:gpgcommand = "gpg --use-agent"
else
let s:gpgcommand = "gpg"
endif
" Section: Autocmd setup {{{1 " Section: Autocmd setup {{{1
augroup GnuPG augroup GnuPG
au! au!
" First make sure nothing is written to ~/.viminfo while editing " First make sure nothing is written to ~/.viminfo while editing
" an encrypted file. " an encrypted file.
autocmd BufNewFile,BufReadPre,FileReadPre *.gpg set viminfo= autocmd BufNewFile,BufReadPre,FileReadPre *.\(gpg\|asc\|pgp\) 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
autocmd BufNewFile,BufReadPre,FileReadPre *.gpg set noswapfile autocmd BufNewFile,BufReadPre,FileReadPre *.\(gpg\|asc\|pgp\) set noswapfile
" 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 " Force the user to edit the recipient list if he opens a new file
autocmd BufNewFile *.gpg call s:GPGEditRecipients() autocmd BufNewFile *.\(gpg\|asc\|pgp\) call s:GPGEditRecipients()
" Switch to binary mode to read the encrypted file " Switch to binary mode to read the encrypted file
autocmd BufReadPre,FileReadPre *.gpg set bin autocmd BufReadPre,FileReadPre *.\(gpg\|asc\|pgp\) set bin
autocmd BufReadPost,FileReadPost *.gpg call s:GPGDecrypt() autocmd BufReadPost,FileReadPost *.\(gpg\|asc\|pgp\) call s:GPGDecrypt()
" Switch to normal mode for editing " Switch to normal mode for editing
autocmd BufReadPost,FileReadPost *.gpg set nobin autocmd BufReadPost,FileReadPost *.\(gpg\|asc\|pgp\) set nobin
" Call the autocommand for the file minus .gpg$ " Call the autocommand for the file minus .gpg$
autocmd BufReadPost,FileReadPost *.gpg execute ":doautocmd BufReadPost " . expand("%:r") autocmd BufReadPost,FileReadPost *.\(gpg\|asc\|pgp\) execute ":doautocmd BufReadPost " . escape(expand("%:r"), ' *?\"'."'")
autocmd BufReadPost,FileReadPost *.gpg execute ":redraw!" autocmd BufReadPost,FileReadPost *.\(gpg\|asc\|pgp\) execute ":redraw!"
" Switch to binary mode before encrypt the file " Switch to binary mode before encrypt the file
autocmd BufWritePre,FileWritePre *.gpg set bin autocmd BufWritePre,FileWritePre *.\(gpg\|asc\|pgp\) set bin
" Convert all text to encrypted text before writing " Convert all text to encrypted text before writing
autocmd BufWritePre,FileWritePre *.gpg call s:GPGEncrypt() autocmd BufWritePre,FileWritePre *.\(gpg\|asc\|pgp\) call s:GPGEncrypt()
" Undo the encryption so we are back in the normal text, directly " Undo the encryption so we are back in the normal text, directly
" after the file has been written. " after the file has been written.
autocmd BufWritePost,FileWritePost *.gpg silent u autocmd BufWritePost,FileWritePost *.\(gpg\|asc\|pgp\) if (exists("b:GPGEncrypted") && b:GPGEncrypted == 1) | silent u | endi
" Switch back to normal mode for editing " Switch back to normal mode for editing
autocmd BufWritePost,FileWritePost *.gpg set nobin autocmd BufWritePost,FileWritePost *.\(gpg\|asc\|pgp\) set nobin
augroup END augroup END
" Section: Highlight setup {{{1 " Section: Highlight setup {{{1
highlight default GPGWarning term=reverse ctermfg=Yellow guifg=Yellow highlight default link GPGWarning WarningMsg
highlight default GPGError term=reverse ctermfg=Red guifg=Red highlight default link GPGError ErrorMsg
highlight default GPGHighlightUnknownRecipient term=reverse ctermfg=Red cterm=underline guifg=Red gui=underline highlight default link GPGHighlightUnknownRecipient ErrorMsg
" Section: Functions {{{1 " Section: Functions {{{1
" Function: s:GPGInit() {{{2
"
" initialize the plugin
"
fun s:GPGInit()
" check if gpg-agent is allowed
if (!exists("g:GPGUseAgent"))
let g:GPGUseAgent = 1
endif
" determine if gnupg can use the gpg-agent
if (exists("$GPG_AGENT_INFO") && g:GPGUseAgent == 1)
if (!exists("$GPG_TTY"))
echohl GPGError
echo "The GPG_TTY is not set!"
echo "gpg-agent might not work."
echohl None
endif
let s:GPGCommand="gpg --use-agent"
else
let s:GPGCommand="gpg --no-use-agent"
endif
" setup shell environment for unix and windows
let s:shellredirsave=&shellredir
let s:shellsave=&shell
if (match(&shell,"\\(cmd\\|command\\).exe") >= 0)
" windows specific settings
let s:shellredir = '>%s'
let s:shell = &shell
let s:stderrredirnull = '2>nul'
else
" unix specific settings
let s:shellredir = &shellredir
let s:shell = 'sh'
let s:stderrredirnull ='2>/dev/null'
let s:GPGCommand="LANG=C " . s:GPGCommand
endi
" find the supported algorithms
let &shellredir=s:shellredir
let &shell=s:shell
let output=system(s:GPGCommand . " --version")
let &shellredir=s:shellredir
let &shell=s:shellsave
let s:GPGPubkey=substitute(output, ".*Pubkey: \\(.\\{-}\\)\n.*", "\\1", "")
let s:GPGCipher=substitute(output, ".*Cipher: \\(.\\{-}\\)\n.*", "\\1", "")
let s:GPGHash=substitute(output, ".*Hash: \\(.\\{-}\\)\n.*", "\\1", "")
let s:GPGCompress=substitute(output, ".*Compress: \\(.\\{-}\\)\n.*", "\\1", "")
endf
" Function: s:GPGDecrypt() {{{2 " Function: s:GPGDecrypt() {{{2
" "
" decrypt the buffer and find all recipients of the encrypted file " decrypt the buffer and find all recipients of the encrypted file
" "
fun s:GPGDecrypt() fun s:GPGDecrypt()
" get the filename of the current buffer " get the filename of the current buffer
let filename=escape(expand("%:p"), ' *?\"'."'") let filename=escape(expand("%:p"), '\"')
" clear GPGRecipients, GPGUnknownRecipients and GPGOptions " clear GPGEncrypted, GPGRecipients, GPGUnknownRecipients and GPGOptions
let b:GPGEncrypted=0
let b:GPGRecipients="" let b:GPGRecipients=""
let b:GPGUnknownRecipients="" let b:GPGUnknownRecipients=""
let b:GPGOptions="" let b:GPGOptions=""
" find the recipients of the file " find the recipients of the file
let output=system(s:gpgcommand . " --decrypt --dry-run --batch " . filename) let &shellredir=s:shellredir
let start=match(output, "ID [[:xdigit:]]\\{8}", 0) let &shell=s:shell
let output=system(s:GPGCommand . " --decrypt --dry-run --batch --no-use-agent --logger-fd 1 \"" . filename . "\"")
let &shellredir=s:shellredir
let &shell=s:shellsave
" check if the file is symmetric/asymmetric encrypted
if (match(output, "gpg: [^ ]\\+ encrypted data") >= 0)
" file is symmetric encrypted
let b:GPGEncrypted=1
let b:GPGOptions=b:GPGOptions . "symmetric:"
let cipher=substitute(output, ".*gpg: \\([^ ]\\+\\) encrypted data.*", "\\1", "")
if (match(s:GPGCipher, "\\<" . cipher . "\\>") >= 0)
let b:GPGOptions=b:GPGOptions . "cipher-algo " . cipher . ":"
else
echohl GPGWarning
echo "The cipher " . cipher . " is not known by the local gpg command. Using default!"
echo
echohl None
endi
elseif (match(output, "gpg: public key decryption") >= 0)
" file is asymmetric encrypted
let b:GPGEncrypted=1
let b:GPGOptions=b:GPGOptions . "encrypt:"
let start=match(output, "ID [[:xdigit:]]\\{8}")
while (start >= 0) while (start >= 0)
let start=start+3 let start=start+3
let recipient=strpart(output, start, 8) let recipient=strpart(output, start, 8)
@ -110,21 +204,28 @@ fun s:GPGDecrypt()
end end
let start=match(output, "ID [[:xdigit:]]\\{8}", start) let start=match(output, "ID [[:xdigit:]]\\{8}", start)
endw endw
elseif (match(output, "gpg: no valid OpenPGP data found") >= 0)
" file is not encrypted
let b:GPGEncrypted=0
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
"echo "GPGRecipients=\"" . b:GPGRecipients . "\"" " check if the message is armored
" Find out if the message is armored
if (stridx(getline(1), "-----BEGIN PGP MESSAGE-----") >= 0) if (stridx(getline(1), "-----BEGIN PGP MESSAGE-----") >= 0)
let b:GPGOptions=b:GPGOptions . "armor:" let b:GPGOptions=b:GPGOptions . "armor:"
endi endi
" finally decrypt the buffer content " finally decrypt the buffer content
" 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 sh temporarily) " we must redirect stderr (using shell temporarily)
let shsave=&sh let &shellredir=s:shellredir
let &sh='sh' let &shell=s:shell
exec "'[,']!" . s:gpgcommand . " --quiet --decrypt 2>/dev/null" exec "'[,']!" . s:GPGCommand . " --quiet --decrypt " . s:stderrredirnull
let &sh=shsave let &shellredir=s:shellredir
let &shell=s:shellsave
if (v:shell_error) " message could not be decrypted if (v:shell_error) " message could not be decrypted
silent u silent u
echohl GPGError echohl GPGError
@ -140,12 +241,22 @@ endf
" encrypts the buffer to all previous recipients " encrypts the buffer to all previous recipients
" "
fun s:GPGEncrypt() fun s:GPGEncrypt()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
let options="" let options=""
let recipients="" let recipients=""
let field=0 let field=0
" built list of options " built list of options
if (exists("b:GPGOptions")) if (!exists("b:GPGOptions") || strlen(b:GPGOptions) == 0)
let b:GPGOptions="encrypt:"
endi
let field=0 let field=0
let option=s:GetField(b:GPGOptions, ":", field) let option=s:GetField(b:GPGOptions, ":", field)
while (strlen(option)) while (strlen(option))
@ -153,20 +264,18 @@ fun s:GPGEncrypt()
let field=field+1 let field=field+1
let option=s:GetField(b:GPGOptions, ":", field) let option=s:GetField(b:GPGOptions, ":", field)
endw endw
endi
" check if there are unknown recipients and warn " check if there are unknown recipients and warn
if (exists("b:GPGUnknownRecipients")) if (exists("b:GPGUnknownRecipients") && strlen(b:GPGUnknownRecipients) > 0)
if (strlen(b:GPGUnknownRecipients) > 0)
echohl GPGWarning echohl GPGWarning
echo "There are unknown recipients!!" echo "There are unknown recipients!!"
echo "Please use GPGEditRecipients to correct!!" echo "Please use GPGEditRecipients to correct!!"
echo
echohl None echohl None
endi endi
endi
" built list of recipients " built list of recipients
if (exists("b:GPGRecipients")) if (exists("b:GPGRecipients") && strlen(b:GPGRecipients) > 0)
let field=0 let field=0
let gpgid=s:GetField(b:GPGRecipients, ":", field) let gpgid=s:GetField(b:GPGRecipients, ":", field)
while (strlen(gpgid)) while (strlen(gpgid))
@ -175,19 +284,31 @@ fun s:GPGEncrypt()
let gpgid=s:GetField(b:GPGRecipients, ":", field) let gpgid=s:GetField(b:GPGRecipients, ":", field)
endw endw
else else
echohl GPGWarning if (match(b:GPGOptions, "encrypt:") >= 0)
echohl GPGError
echo "There are no recipients!!" echo "There are no recipients!!"
echo "Please use GPGEditRecipients to correct!!" echo "Please use GPGEditRecipients to correct!!"
echo
echohl None echohl None
endi endi
endi
" encrypt the buffer " encrypt the buffer
let shsave=&sh let &shellredir=s:shellredir
let &sh='sh' let &shell=s:shell
exec "'[,']!" . s:gpgcommand . " --quiet --no-encrypt-to --encrypt " . options . recipients . " 2>/dev/null" silent exec "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . recipients . " " . s:stderrredirnull
let &sh=shsave let &shellredir=s:shellredir
let &shell=s:shellsave
if (v:shell_error) " message could not be encrypted
silent u
echohl GPGError
let asd=input("Message could not be encrypted! File might be empty! (Press ENTER)")
echohl None
bwipeout
return
endi
redraw! "redraw!
endf endf
" Function: s:GPGViewRecipients() {{{2 " Function: s:GPGViewRecipients() {{{2
@ -195,6 +316,14 @@ endf
" echo the recipients " echo the recipients
" "
fun s:GPGViewRecipients() fun s:GPGViewRecipients()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
if (exists("b:GPGRecipients")) if (exists("b:GPGRecipients"))
echo 'This file has following recipients (Unknown recipients have a prepended "!"):' echo 'This file has following recipients (Unknown recipients have a prepended "!"):'
" echo the recipients " echo the recipients
@ -235,18 +364,40 @@ endf
" create a scratch buffer with all recipients to add/remove recipients " create a scratch buffer with all recipients to add/remove recipients
" "
fun s:GPGEditRecipients() fun s:GPGEditRecipients()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
" only do this if it isn't already a GPGRecipients_* buffer " only do this if it isn't already a GPGRecipients_* buffer
if (match(bufname("%"), "GPGRecipients_") != 0 && match(bufname("%"), "\.gpg$") >= 0) if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0)
" save buffer name " save buffer name
let buffername=bufname("%") let buffername=bufname("%")
let editbuffername="GPGRecipients_" . buffername let editbuffername="GPGRecipients_" . buffername
" create scratch buffer
exe 'silent! split ' . editbuffername
" check if this buffer exists " check if this buffer exists
if (bufexists(editbuffername)) if (!bufexists(editbuffername))
" create scratch buffer
exe 'silent! split ' . escape(editbuffername, ' *?\"'."'")
" add a autocommand to regenerate the recipients after a write
autocmd BufHidden,BufUnload <buffer> call s:GPGFinishRecipientsBuffer()
else
if (bufwinnr(editbuffername) >= 0)
" switch to scratch buffer window
exe 'silent! ' . bufwinnr(editbuffername) . "wincmd w"
else
" split scratch buffer window
exe 'silent! sbuffer ' . escape(editbuffername, ' *?\"'."'")
" add a autocommand to regenerate the recipients after a write
autocmd BufHidden,BufUnload <buffer> call s:GPGFinishRecipientsBuffer()
endi
" empty the buffer " empty the buffer
silent normal! 1GdG silent normal! 1GdG
endi endi
@ -266,7 +417,7 @@ fun s:GPGEditRecipients()
silent put ='GPG: Please edit the list of recipients, one recipient per line' silent put ='GPG: Please edit the list of recipients, one recipient per line'
silent put ='GPG: Unknown recipients have a prepended \"!\"' silent put ='GPG: Unknown recipients have a prepended \"!\"'
silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically' silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically'
silent put ='GPG: Use :x or :bd to close this buffer' silent put ='GPG: Closing this buffer commits changes'
silent put ='GPG: ----------------------------------------------------------------------' silent put ='GPG: ----------------------------------------------------------------------'
" put the recipients in the scratch buffer " put the recipients in the scratch buffer
@ -314,27 +465,35 @@ fun s:GPGEditRecipients()
silent normal! 1Gdd silent normal! 1Gdd
" jump to the first recipient " jump to the first recipient
silent normal! 6G silent normal! G
" add a autocommand to regenerate the recipients after a write
augroup GPGEditRecipients
augroup END
execute 'au GPGEditRecipients BufHidden ' . editbuffername . ' call s:GPGFinishRecipientsBuffer()'
endi endi
endf endf
" Function: s:GPGFinishRecipientsBuffer() {{{2 " Function: s:GPGFinishRecipientsBuffer() {{{2
" "
" create a new recipient list from RecipientsBuffer " create a new recipient list from RecipientsBuffer
fun s:GPGFinishRecipientsBuffer() fun s:GPGFinishRecipientsBuffer()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
" go to buffer before doing work
if (bufnr("%") != expand("<abuf>"))
" switch to scratch buffer window
exe 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w"
endi
" clear GPGRecipients and GPGUnknownRecipients " clear GPGRecipients and GPGUnknownRecipients
let GPGRecipients="" let GPGRecipients=""
let GPGUnknownRecipients="" let GPGUnknownRecipients=""
" delete the autocommand " delete the autocommand
exe "au! GPGEditRecipients * " . bufname("%") autocmd! * <buffer>
let currentline=1 let currentline=1
let recipient=getline(currentline) let recipient=getline(currentline)
@ -365,11 +524,11 @@ fun s:GPGFinishRecipientsBuffer()
endw endw
" write back the new recipient list to the corresponding buffer and mark it " write back the new recipient list to the corresponding buffer and mark it
" as modified " as modified. Buffer is now for sure a encrypted buffer.
call setbufvar(b:corresponding_to, "GPGRecipients", GPGRecipients) call setbufvar(b:corresponding_to, "GPGRecipients", GPGRecipients)
call setbufvar(b:corresponding_to, "GPGUnknownRecipients", GPGUnknownRecipients) call setbufvar(b:corresponding_to, "GPGUnknownRecipients", GPGUnknownRecipients)
call setbufvar(b:corresponding_to, "&mod", 1) call setbufvar(b:corresponding_to, "&mod", 1)
"echo "GPGRecipients=\"" . getbufvar(b:corresponding_to, "GPGRecipients") . "\"" call setbufvar(b:corresponding_to, "GPGEncrypted", 1)
" check if there is any known recipient " check if there is any known recipient
if (strlen(s:GetField(GPGRecipients, ":", 0)) == 0) if (strlen(s:GetField(GPGRecipients, ":", 0)) == 0)
@ -377,7 +536,175 @@ fun s:GPGFinishRecipientsBuffer()
echo 'There are no known recipients!' echo 'There are no known recipients!'
echohl None echohl None
endi endi
endf
" Function: s:GPGViewOptions() {{{2
"
" echo the recipients
"
fun s:GPGViewOptions()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
if (exists("b:GPGOptions"))
echo 'This file has following options:'
" echo the options
let field=0
let option=s:GetField(b:GPGOptions, ":", field)
while (strlen(option) > 0)
echo option
let field=field+1
let option=s:GetField(b:GPGOptions, ":", field)
endw
endi
endf
" Function: s:GPGEditOptions() {{{2
"
" create a scratch buffer with all recipients to add/remove recipients
"
fun s:GPGEditOptions()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
" only do this if it isn't already a GPGOptions_* buffer
if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0)
" save buffer name
let buffername=bufname("%")
let editbuffername="GPGOptions_" . buffername
" check if this buffer exists
if (!bufexists(editbuffername))
" create scratch buffer
exe 'silent! split ' . escape(editbuffername, ' *?\"'."'")
" add a autocommand to regenerate the options after a write
autocmd BufHidden,BufUnload <buffer> call s:GPGFinishOptionsBuffer()
else
if (bufwinnr(editbuffername) >= 0)
" switch to scratch buffer window
exe 'silent! ' . bufwinnr(editbuffername) . "wincmd w"
else
" split scratch buffer window
exe 'silent! sbuffer ' . escape(editbuffername, ' *?\"'."'")
" add a autocommand to regenerate the options after a write
autocmd BufHidden,BufUnload <buffer> call s:GPGFinishOptionsBuffer()
endi
" empty the buffer
silent normal! 1GdG
endi
" Mark the buffer as a scratch buffer
setlocal buftype=nofile
setlocal noswapfile
setlocal nowrap
setlocal nobuflisted
setlocal nonumber
" so we know for which other buffer this edit buffer is
let b:corresponding_to=buffername
" put some comments to the scratch buffer
silent put ='GPG: ----------------------------------------------------------------------'
silent put ='GPG: THERE IS NO CHECK OF THE ENTERED OPTIONS!'
silent put ='GPG: YOU NEED TO KNOW WHAT YOU ARE DOING!'
silent put ='GPG: IF IN DOUBT, QUICKLY EXIT USING :x OR :bd'
silent put ='GPG: Please edit the list of options, one option per line'
silent put ='GPG: Please refer to the gpg documentation for valid options'
silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically'
silent put ='GPG: Closing this buffer commits changes'
silent put ='GPG: ----------------------------------------------------------------------'
" put the options in the scratch buffer
let options=getbufvar(b:corresponding_to, "GPGOptions")
let field=0
let option=s:GetField(options, ":", field)
while (strlen(option) > 0)
silent put =option
let field=field+1
let option=s:GetField(options, ":", field)
endw
" delete the empty first line
silent normal! 1Gdd
" jump to the first option
silent normal! G
" define highlight
if (has("syntax") && exists("g:syntax_on"))
syntax match GPGComment "^GPG:.*$"
highlight clear GPGComment
highlight link GPGComment Comment
endi
endi
endf
" Function: s:GPGFinishOptionsBuffer() {{{2
"
" create a new option list from OptionsBuffer
fun s:GPGFinishOptionsBuffer()
" guard for unencrypted files
if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
echohl GPGWarning
echo "File is not encrypted, all GPG functions disabled!"
echohl None
return
endi
" go to buffer before doing work
if (bufnr("%") != expand("<abuf>"))
" switch to scratch buffer window
exe 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w"
endi
" clear GPGOptions and GPGUnknownOptions
let GPGOptions=""
let GPGUnknownOptions=""
" delete the autocommand
autocmd! * <buffer>
let currentline=1
let option=getline(currentline)
" get the options from the scratch buffer
while (currentline <= line("$"))
" delete all spaces at beginning and end of the line
" also delete a '!' at the beginning of the line
let option=substitute(option, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "")
" delete comment lines
let option=substitute(option, "^GPG:.*$", "", "")
" only do this if the line is not empty
if (strlen(option) > 0)
let GPGOptions=GPGOptions . option . ":"
endi
let currentline=currentline+1
let option=getline(currentline)
endw
" write back the new option list to the corresponding buffer and mark it
" as modified
call setbufvar(b:corresponding_to, "GPGOptions", GPGOptions)
call setbufvar(b:corresponding_to, "&mod", 1)
endf endf
@ -387,7 +714,11 @@ endf
" Returns: ID for the given name " Returns: ID for the given name
fun s:GPGNameToID(name) fun s:GPGNameToID(name)
" ask gpg for the id for a name " ask gpg for the id for a name
let output=system(s:gpgcommand . " --quiet --with-colons --fixed-list-mode --list-keys \"" . a:name . "\"") let &shellredir=s:shellredir
let &shell=s:shell
let output=system(s:GPGCommand . " --quiet --with-colons --fixed-list-mode --list-keys \"" . a:name . "\"")
let &shellredir=s:shellredir
let &shell=s:shellsave
" parse the output of gpg " parse the output of gpg
let pub_seen=0 let pub_seen=0
@ -447,7 +778,11 @@ fun s:GPGIDToName(identity)
" TODO is the encryption subkey really unique? " TODO is the encryption subkey really unique?
" ask gpg for the id for a name " ask gpg for the id for a name
let output=system(s:gpgcommand . " --quiet --with-colons --fixed-list-mode --list-keys " . a:identity ) let &shellredir=s:shellredir
let &shell=s:shell
let output=system(s:GPGCommand . " --quiet --with-colons --fixed-list-mode --list-keys " . a:identity )
let &shellredir=s:shellredir
let &shell=s:shellsave
" parse the output of gpg " parse the output of gpg
let pub_seen=0 let pub_seen=0
@ -507,5 +842,7 @@ endf
" Section: Command definitions {{{1 " Section: Command definitions {{{1
com! GPGViewRecipients call s:GPGViewRecipients() com! GPGViewRecipients call s:GPGViewRecipients()
com! GPGEditRecipients call s:GPGEditRecipients() com! GPGEditRecipients call s:GPGEditRecipients()
com! GPGViewOptions call s:GPGViewOptions()
com! GPGEditOptions call s:GPGEditOptions()
" vim600: set foldmethod=marker: " vim600: set foldmethod=marker: