r1291 - in /trunk/packages/vim-scripts: debian/changelog debian/vim-scripts.status html/index.html html/plugin_gnupg.vim.html plugin/gnupg.vim

jamessan at users.alioth.debian.org jamessan at users.alioth.debian.org
Fri Dec 5 21:27:23 UTC 2008


Author: jamessan
Date: Fri Dec  5 21:27:23 2008
New Revision: 1291

URL: http://svn.debian.org/wsvn/pkg-vim/?sc=1&rev=1291
Log:
Updated gnupg

Modified:
    trunk/packages/vim-scripts/debian/changelog
    trunk/packages/vim-scripts/debian/vim-scripts.status
    trunk/packages/vim-scripts/html/index.html
    trunk/packages/vim-scripts/html/plugin_gnupg.vim.html
    trunk/packages/vim-scripts/plugin/gnupg.vim

Modified: trunk/packages/vim-scripts/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/debian/changelog?rev=1291&op=diff
==============================================================================
--- trunk/packages/vim-scripts/debian/changelog (original)
+++ trunk/packages/vim-scripts/debian/changelog Fri Dec  5 21:27:23 2008
@@ -1,7 +1,8 @@
 vim-scripts (20081205-1) UNRELEASED; urgency=low
 
   * Updated addons:
-    - supertab, NERD_commenter, xmledit (Closes: #503707), vcscommand, Align
+    - supertab, NERD_commenter, xmledit (Closes: #503707), vcscommand, Align,
+      gnupg
   * Renamed addons:
     - themes => color_sample_pack
 

Modified: trunk/packages/vim-scripts/debian/vim-scripts.status
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/debian/vim-scripts.status?rev=1291&op=diff
==============================================================================
--- trunk/packages/vim-scripts/debian/vim-scripts.status (original)
+++ trunk/packages/vim-scripts/debian/vim-scripts.status Fri Dec  5 21:27:23 2008
@@ -69,7 +69,7 @@
 email:       markus.braun at krawel.de
 license:     GNU GPL, see /usr/share/common-licenses/GPL
 disabledby:  let loaded_gnupg = 1
-version:     1933
+version:     2276
 
 script_name: plugin/taglist.vim
 addon:       taglist

Modified: trunk/packages/vim-scripts/html/index.html
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/html/index.html?rev=1291&op=diff
==============================================================================
--- trunk/packages/vim-scripts/html/index.html (original)
+++ trunk/packages/vim-scripts/html/index.html Fri Dec  5 21:27:23 2008
@@ -51,7 +51,7 @@
    <li><a href="syntax_mkd.vim.html">syntax/mkd.vim.html</a></li>
   </ul>
   <p>
-  Page generated on Fri, 05 Dec 2008 14:57:57 -0500
+  Page generated on Fri, 05 Dec 2008 16:26:22 -0500
 .
   </p>
  </body>

Modified: trunk/packages/vim-scripts/html/plugin_gnupg.vim.html
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/html/plugin_gnupg.vim.html?rev=1291&op=diff
==============================================================================
--- trunk/packages/vim-scripts/html/plugin_gnupg.vim.html (original)
+++ trunk/packages/vim-scripts/html/plugin_gnupg.vim.html Fri Dec  5 21:27:23 2008
@@ -153,8 +153,8 @@
 <tr>
   <td class="lightbg"><b>&nbsp;script karma&nbsp;</b></td>
   <td>
-    Rating <b>604/218</b>,
-    Downloaded by 4049  </td>
+    Rating <b>782/276</b>,
+    Downloaded by 5574  </td>
 </tr>
 </table>
 <p>
@@ -167,10 +167,10 @@
 <tr><td>utility</td></tr>
 <tr><td>&nbsp;</td></tr>
 <tr><td class="prompt">description</td></tr>
-<tr><td>This script implements transparent editing of gpg symmetric and asymmetric encrypted files. The filename must have a &quot;.gpg&quot;, &quot;.pgp&quot; or &quot;.asc&quot; suffix. When opening such 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 encrypted to all recipients or the script asks for a passphrase before it is written. The script turns off viminfo and swapfile to increase security.
<br>
<br>Commands:
<br>
<br>&nbsp;&nbsp;:GPGEditRecipients
<br>&nbsp;&nbsp;&nbsp;&nbsp;Opens a scratch buffer to change the list of recipients. Recipients that
<br>&nbsp;&nbsp;&nbsp;&nbsp;are unknown (not in your public keyring) are highlighted and have
<br>&nbsp;&nbsp;&nbsp;&nbsp;a prepended &quot;!&quot;. Closing the buffer makes the changes permanent.
<br>
<br>&nbsp;&nbsp;:GPGViewRecipients
<br>&nbsp;&nbsp;&nbsp;&nbsp;Prints the list of recipients.
<br>
<br>&nbsp;&nbsp;:GPGEditOptions
<br>&nbsp;&nbsp;&nbsp;&nbsp;Opens a scratch buffer to change the options for encryption (symmetric,
<br>&nbsp;&nbsp;&nbsp;&nbsp;asymmetric, signing). Closing the buffer makes the changes permanent.
<br>&nbsp;&nbsp;&nbsp;&nbsp;WARNING: There is no check of the entered options, so you need to know
<br>&nbsp;&nbsp;&nbsp;&nbsp;what you are doing.
<br>
<br>&nbsp;&nbsp;:GPGViewOptions
<br>&nbsp;&nbsp;&nbsp;&nbsp;Prints the list of options.
<br>
<br>Variables:
<br>
<br>&nbsp;&nbsp;g:GPGUseAgent
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set to 0 a possible available gpg-agent won't be used. Defaults to 1.
<br>
<br>&nbsp;&nbsp;g:GPGPreferSymmetric
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set to 1 symmetric encryption is preferred for new files. Defaults to 0.
<br>
<br>&nbsp;&nbsp;g:GPGPreferArmor
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set to 1 armored data is preferred for new files. Defaults to 0.</td></tr>
+<tr><td>This script implements transparent editing of gpg encrypted files. The filename must have a &quot;.gpg&quot;, &quot;.pgp&quot; or &quot;.asc&quot; suffix. When opening such 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 encrypted to all recipients before it is written. The script turns off viminfo and swapfile to increase security.
<br>
<br>Commands:
<br>
<br>&nbsp;&nbsp;:GPGEditRecipients
<br>&nbsp;&nbsp;&nbsp;&nbsp;Opens a scratch buffer to change the list of recipients. Recipients that
<br>&nbsp;&nbsp;&nbsp;&nbsp;are unknown (not in your public key) are highlighted and have
<br>&nbsp;&nbsp;&nbsp;&nbsp;a prepended &quot;!&quot;. Closing the buffer makes the changes permanent.
<br>
<br>&nbsp;&nbsp;:GPGViewRecipients
<br>&nbsp;&nbsp;&nbsp;&nbsp;Prints the list of recipients.
<br>
<br>&nbsp;&nbsp;:GPGEditOptions
<br>&nbsp;&nbsp;&nbsp;&nbsp;Opens a scratch buffer to change the options for encryption (symmetric,
<br>&nbsp;&nbsp;&nbsp;&nbsp;asymmetric, signing). Closing the buffer makes the changes permanent.
<br>&nbsp;&nbsp;&nbsp;&nbsp;WARNING: There is no check of the entered options, so you need to know
<br>&nbsp;&nbsp;&nbsp;&nbsp;what you are doing.
<br>
<br>&nbsp;&nbsp;:GPGViewOptions
<br>&nbsp;&nbsp;&nbsp;&nbsp;Prints the list of options.
<br>
<br>Variables:
<br>
<br>&nbsp;&nbsp;g:GPGExecutable
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set used as gpg executable, otherwise the system chooses what is run
<br>&nbsp;&nbsp;&nbsp;&nbsp;when &quot;gpg&quot; is called. Defaults to &quot;gpg&quot;.
<br>
<br>&nbsp;&nbsp;g:GPGUseAgent
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set to 0 a possible available gpg-agent won't be used. Defaults to 1.
<br>
<br>&nbsp;&nbsp;g:GPGPreferSymmetric
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set to 1 symmetric encryption is preferred for new files. Defaults to 0.
<br>
<br>&nbsp;&nbsp;g:GPGPreferArmor
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set to 1 armored data is preferred for new files. Defaults to 0.
<br>
<br>&nbsp;&nbsp;g:GPGDefaultRecipients
<br>&nbsp;&nbsp;&nbsp;&nbsp;If set, these recipients are used as defaults when no other recipient is
<br>&nbsp;&nbsp;&nbsp;&nbsp;defined. This variable is a Vim list. Default is unset.</td></tr>
 <tr><td>&nbsp;</td></tr>
 <tr><td class="prompt">install details</td></tr>
-<tr><td>Copy the gnupg.vim file to the $HOME/.vim/plugin directory. Refer to ':help add-plugin', ':help add-global-plugin' and ':help runtimepath' for more details about Vim plugins.</td></tr>
+<tr><td>Copy the gnupg.vim file to the $HOME/.vim/plugin directory. Refer to ':help add-plugin', ':help add-global-plugin' and ':help runtimepath' for more details about Vim plugins.
<br>
<br>From &quot;man 1 gpg-agent&quot;:
<br>...
<br>You should always add the following lines to your .bashrc or whatever initialization file is used for all shell invocations:
<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp; GPG_TTY=‘tty‘
<br>&nbsp;&nbsp;&nbsp;&nbsp; export GPG_TTY
<br>
<br>It is important that this environment variable always reflects the output of the tty command. For W32 systems this option is not required.
<br>...</td></tr>
 <tr><td>&nbsp;</td></tr>
 </table>
 
@@ -204,6 +204,22 @@
     <th valign="top">release notes</th>
 </tr>
 <tr>
+        <td class="rowodd" valign="top" nowrap><a href="download_script.php?src_id=9142">gnupg.vim</a></td>
+    <td class="rowodd" valign="top" nowrap><b>2276</b></td>
+    <td class="rowodd" valign="top" nowrap><i>2008-08-18</i></td>
+    <td class="rowodd" valign="top" nowrap>7.0</td>
+    <td class="rowodd" valign="top"><i><a href="/account/profile.php?user_id=1120">Markus Braun</a></i></td>
+    <td class="rowodd" valign="top" width="2000">- added support for default recipients via the variable g:GPGDefaultRecipients.
<br>- fixed an wrong error message with symmetric encryption and set recipients (thanks to Sebastian Luettich).
<br>- create a empty new buffer on leaving vim to wipe out sensitive data on console.
<br>- make sure senisitive data is never written unencrypted to disk.</td>
+</tr>
+<tr>
+        <td class="roweven" valign="top" nowrap><a href="download_script.php?src_id=9058">gnupg.vim</a></td>
+    <td class="roweven" valign="top" nowrap><b>2249</b></td>
+    <td class="roweven" valign="top" nowrap><i>2008-07-31</i></td>
+    <td class="roweven" valign="top" nowrap>7.0</td>
+    <td class="roweven" valign="top"><i><a href="/account/profile.php?user_id=1120">Markus Braun</a></i></td>
+    <td class="roweven" valign="top" width="2000">- rewritten lots of code to use lists feature of vim 7 instead of my own implementation
<br>- added a n option to change the name and location of GPG executable
<br>- try to get GPG_TTY dynamically.</td>
+</tr>
+<tr>
         <td class="rowodd" valign="top" nowrap><a href="download_script.php?src_id=8174">gnupg.vim</a></td>
     <td class="rowodd" valign="top" nowrap><b>1933</b></td>
     <td class="rowodd" valign="top" nowrap><i>2008-01-23</i></td>
@@ -249,6 +265,7 @@
         </tr>
       </table>
     </td>
+
   </tr>
 </table>
 
@@ -287,8 +304,7 @@
           </td>
 
     <td align="right" valign="top">
-      	<a href="http://www.webconceptgroup.net"><img src="/images/logo_sponsor_wcg.jpg" width="131" height="30" border="0" alt="Sponsored by Web Concept Group Inc."></a>
-	<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=8&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" /></a>
+      		<a href="http://sourceforge.net" rel="nofollow"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=8&type=1" width="88" height="31" border="0" alt="SourceForge.net Logo" /></a>
     </td>
 
     <td><img src="/images/spacer.gif" width="5" height="1" alt=""></td>

Modified: trunk/packages/vim-scripts/plugin/gnupg.vim
URL: http://svn.debian.org/wsvn/pkg-vim/trunk/packages/vim-scripts/plugin/gnupg.vim?rev=1291&op=diff
==============================================================================
--- trunk/packages/vim-scripts/plugin/gnupg.vim (original)
+++ trunk/packages/vim-scripts/plugin/gnupg.vim Fri Dec  5 21:27:23 2008
@@ -1,5 +1,5 @@
 " Name: gnupg.vim
-" Version:  $Id: gnupg.vim 1933 2008-01-23 09:49:33Z mbr $
+" Version:  $Id: gnupg.vim 2276 2008-08-15 12:50:33Z mbr $
 " Author:   Markus Braun <markus.braun at krawel.de>
 " Summary:  Vim plugin for transparent editing of gpg encrypted files.
 " Licence:  This program is free software; you can redistribute it and/or
@@ -21,6 +21,19 @@
 "   Refer to ':help add-plugin', ':help add-global-plugin' and ':help
 "   runtimepath' for more details about Vim plugins.
 "
+"   From "man 1 gpg-agent":
+"
+"   ...
+"   You should always add the following lines to your .bashrc or whatever
+"   initialization file is used for all shell invocations:
+"
+"        GPG_TTY=‘tty‘
+"        export GPG_TTY
+"
+"   It is important that this environment variable always reflects the out‐
+"   put of the tty command. For W32 systems this option is not required.
+"   ...
+"
 " Commands:
 "
 "   :GPGEditRecipients
@@ -42,6 +55,10 @@
 "
 " Variables:
 "
+"   g:GPGExecutable
+"     If set used as gpg executable, otherwise the system chooses what is run
+"     when "gpg" is called. Defaults to "gpg".
+"
 "   g:GPGUseAgent
 "     If set to 0 a possible available gpg-agent won't be used. Defaults to 1.
 "
@@ -51,37 +68,55 @@
 "   g:GPGPreferArmor
 "     If set to 1 armored data is preferred for new files. Defaults to 0.
 "
+"   g:GPGDefaultRecipients
+"     If set, these recipients are used as defaults when no other recipient is
+"     defined. This variable is a Vim list. Default is unset.
+"
 " Credits:
-"   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
+" - 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.
-"   Lars Becker for patch to make gpg2 working.
+" - Lars Becker for patch to make gpg2 working.
+" - Thomas Arendsen Hein for patch to convert encoding of gpg output
+" - Karl-Heinz Ruskowski for patch to fix unknown recipients and trust model
+"   and patient beta testing.
+" - Giel van Schijndel for patch to get GPG_TTY dynamically.
+" - Sebastian Luettich for patch to fix issue with symmetric encryption an set
+"   recipients.
 "
 " Section: Plugin header {{{1
+if (v:version < 700)
+  echohl ErrorMsg | echo 'plugin gnupg.vim requires Vim version >= 7.0' | echohl None
+  finish
+endif
+
 if (exists("g:loaded_gnupg") || &cp || exists("#BufReadPre#*.\(gpg\|asc\|pgp\)"))
   finish
-endi
-let g:loaded_gnupg = "$Revision: 1933 $"
+endif
+
+let g:loaded_gnupg = "$Revision: 2276 $"
 
 " Section: Autocmd setup {{{1
 augroup GnuPG
-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() | endi
-" do the decryption
-autocmd BufReadPost,FileReadPost               *.\(gpg\|asc\|pgp\) call s:GPGDecrypt()
-
-" convert all text to encrypted text before writing
-autocmd BufWritePre,FileWritePre               *.\(gpg\|asc\|pgp\) call s:GPGEncrypt()
-" undo the encryption so we are back in the normal text, directly
-" after the file has been written.
-autocmd BufWritePost,FileWritePost             *.\(gpg\|asc\|pgp\) call s:GPGEncryptPost()
-
+  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
+  autocmd BufReadPost,FileReadPost               *.\(gpg\|asc\|pgp\) call s:GPGDecrypt()
+
+  " convert all text to encrypted text before writing
+  autocmd BufWritePre,FileWritePre               *.\(gpg\|asc\|pgp\) call s:GPGEncrypt()
+  " undo the encryption so we are back in the normal text, directly
+  " after the file has been written.
+  autocmd BufWritePost,FileWritePost             *.\(gpg\|asc\|pgp\) call s:GPGEncryptPost()
+
+  " cleanup on leaving vim
+  autocmd VimLeave                               *.\(gpg\|asc\|pgp\) call s:GPGCleanup()
 augroup END
 
 " Section: Highlight setup {{{1
@@ -94,13 +129,18 @@
 "
 " initialize the plugin
 "
-fun s:GPGInit()
+function s:GPGInit()
   " first make sure nothing is written to ~/.viminfo while editing
   " an encrypted file.
-  set viminfo=
+  set viminfo= 
 
   " we don't want a swap file, as it writes unencrypted data to disk
   set noswapfile
+
+  " check what gpg command to use
+  if (!exists("g:GPGExecutable"))
+    let g:GPGExecutable = "gpg --trust-model always"
+  endif
 
   " check if gpg-agent is allowed
   if (!exists("g:GPGUseAgent"))
@@ -118,37 +158,46 @@
   endif
 
   " check if debugging is turned on
+  if (!exists("g:GPGDefaultRecipients"))
+    let g:GPGDefaultRecipients = []
+  endif
+
+  " check if debugging is turned on
   if (!exists("g:GPGDebugLevel"))
     let g:GPGDebugLevel = 0
   endif
- 
+
   " print version
   call s:GPGDebug(1, "gnupg.vim ". g:loaded_gnupg)
 
   " 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"
+    if (!exists("$GPG_TTY") && !has("gui_running"))
+      let $GPG_TTY = system("tty")
+      if (v:shell_error)
+        let $GPG_TTY = ""
+        echohl GPGError
+        echom "The GPG_TTY is not set and no TTY could be found using the `tty` command!"
+        echom "gpg-agent might not work."
+        echohl None
+      endif
+    endif
+    let s:GPGCommand = g:GPGExecutable . " --use-agent"
   else
-    let s:GPGCommand="gpg --no-use-agent"
+    let s:GPGCommand = g:GPGExecutable . " --no-use-agent"
   endif
 
   " don't use tty in gvim
   " FIXME find a better way to avoid an error.
   "       with this solution only --use-agent will work
-  if has("gui_running")
-    let s:GPGCommand=s:GPGCommand . " --no-tty"
+  if (has("gui_running"))
+    let s:GPGCommand = s:GPGCommand . " --no-tty"
   endif
 
   " setup shell environment for unix and windows
-  let s:shellredirsave=&shellredir
-  let s:shellsave=&shell
-  if (match(&shell,"\\(cmd\\|command\\).exe") >= 0)
+  let s:shellredirsave = &shellredir
+  let s:shellsave = &shell
+  if (match(&shell,"\\(cmd\\|command\\).execute") >= 0)
     " windows specific settings
     let s:shellredir = '>%s'
     let s:shell = &shell
@@ -157,125 +206,136 @@
     " unix specific settings
     let s:shellredir = &shellredir
     let s:shell = 'sh'
-    let s:stderrredirnull ='2>/dev/null'
-    let s:GPGCommand="LANG=C LC_ALL=C " . s:GPGCommand
-  endi
+    let s:stderrredirnull = '2>/dev/null'
+    let s:GPGCommand = "LANG=C LC_ALL=C " . s:GPGCommand
+  endif
 
   " find the supported algorithms
-  let &shellredir=s:shellredir
-  let &shell=s:shell
-  let output=system(s:GPGCommand . " --version")
-  let &shellredir=s:shellredirsave
-  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
+  let &shellredir = s:shellredir
+  let &shell = s:shell
+  let output = system(s:GPGCommand . " --version")
+  let &shellredir = s:shellredirsave
+  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", "")
+endfunction
+
+" Function: s:GPGCleanup() {{{2
+"
+" cleanup on leaving vim
+"
+function s:GPGCleanup()
+  " wipe out screen
+  new +only
+  redraw!
+endfunction
 
 " Function: s:GPGDecrypt() {{{2
 "
 " decrypt the buffer and find all recipients of the encrypted file
 "
-fun s:GPGDecrypt()
+function s:GPGDecrypt()
   " switch to binary mode to read the encrypted file
   set bin
 
   " get the filename of the current buffer
-  let filename=escape(expand("%:p"), '\"')
-
-  " clear GPGEncrypted, GPGRecipients, GPGUnknownRecipients and GPGOptions
-  let b:GPGEncrypted=0
-  let b:GPGRecipients=""
-  let b:GPGUnknownRecipients=""
-  let b:GPGOptions=""
+  let filename = escape(expand("%:p"), '\"')
+
+  " clear GPGEncrypted, GPGRecipients and GPGOptions
+  let b:GPGEncrypted = 0
+  let b:GPGRecipients = []
+  let b:GPGOptions = []
 
   " find the recipients of the file
-  let &shellredir=s:shellredir
-  let &shell=s:shell
-  let output=system(s:GPGCommand . " --verbose --decrypt --list-only --dry-run --batch --no-use-agent --logger-fd 1 \"" . filename . "\"")
-  let &shellredir=s:shellredirsave
-  let &shell=s:shellsave
+  let &shellredir = s:shellredir
+  let &shell = s:shell
+  let output = system(s:GPGCommand . " --verbose --decrypt --list-only --dry-run --batch --no-use-agent --logger-fd 1 \"" . filename . "\"")
+  let &shellredir = s:shellredirsave
+  let &shell = s:shellsave
   call s:GPGDebug(1, "output of command '" . s:GPGCommand . " --verbose --decrypt --list-only --dry-run --batch --no-use-agent --logger-fd 1 \"" . filename . "\"' is:")
   call s:GPGDebug(1, ">>>>> " . output . " <<<<<")
 
   " check if the file is symmetric/asymmetric encrypted
   if (match(output, "gpg: encrypted with [[:digit:]]\\+ passphrase") >= 0)
     " file is symmetric encrypted
-    let b:GPGEncrypted=1
+    let b:GPGEncrypted = 1
     call s:GPGDebug(1, "this file is symmetric encrypted")
 
-    let b:GPGOptions=b:GPGOptions . "symmetric:"
-
-    let cipher=substitute(output, ".*gpg: \\([^ ]\\+\\) encrypted data.*", "\\1", "")
+    let b:GPGOptions += ["symmetric"]
+
+    " find the used cipher algorithm
+    let cipher = substitute(output, ".*gpg: \\([^ ]\\+\\) encrypted data.*", "\\1", "")
     if (match(s:GPGCipher, "\\<" . cipher . "\\>") >= 0)
-      let b:GPGOptions=b:GPGOptions . "cipher-algo " . cipher . ":"
+      let b:GPGOptions += ["cipher-algo " . cipher]
       call s:GPGDebug(1, "cipher-algo is " . cipher)
     else
       echohl GPGWarning
-      echo "The cipher " . cipher . " is not known by the local gpg command. Using default!"
+      echom "The cipher " . cipher . " is not known by the local gpg command. Using default!"
       echo
       echohl None
-    endi
+    endif
   elseif (match(output, "gpg: public key is [[:xdigit:]]\\{8}") >= 0)
     " file is asymmetric encrypted
-    let b:GPGEncrypted=1
+    let b:GPGEncrypted = 1
     call s:GPGDebug(1, "this file is asymmetric encrypted")
 
-    let b:GPGOptions=b:GPGOptions . "encrypt:"
-
-    let start=match(output, "gpg: public key is [[:xdigit:]]\\{8}")
+    let b:GPGOptions += ["encrypt"]
+
+    " find the used public keys
+    let start = match(output, "gpg: public key is [[:xdigit:]]\\{8}")
     while (start >= 0)
-      let start=start + strlen("gpg: public key is ")
-      let recipient=strpart(output, start, 8)
+      let start = start + strlen("gpg: public key is ")
+      let recipient = strpart(output, start, 8)
       call s:GPGDebug(1, "recipient is " . recipient)
-      let name=s:GPGNameToID(recipient)
+      let name = s:GPGNameToID(recipient)
       if (strlen(name) > 0)
-	let b:GPGRecipients=b:GPGRecipients . name . ":" 
+        let b:GPGRecipients += [name]
         call s:GPGDebug(1, "name of recipient is " . name)
       else
-	let b:GPGUnknownRecipients=b:GPGUnknownRecipients . recipient . ":" 
-	echohl GPGWarning
-	echo "The recipient " . recipient . " is not in your public keyring!"
-	echohl None
+        let b:GPGRecipients += [recipient]
+        echohl GPGWarning
+        echom "The recipient \"" . recipient . "\" is not in your public keyring!"
+        echohl None
       end
-      let start=match(output, "gpg: public key is [[:xdigit:]]\\{8}", start)
-    endw
+      let start = match(output, "gpg: public key is [[:xdigit:]]\\{8}", start)
+    endwhile
   else
     " file is not encrypted
-    let b:GPGEncrypted=0
+    let b:GPGEncrypted = 0
     call s:GPGDebug(1, "this file is not encrypted")
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     set nobin
     return
-  endi
+  endif
 
   " check if the message is armored
   if (match(output, "gpg: armor header") >= 0)
     call s:GPGDebug(1, "this file is armored")
-    let b:GPGOptions=b:GPGOptions . "armor:"
-  endi
+    let b:GPGOptions += ["armor"]
+  endif
 
   " finally decrypt the buffer content
   " since even with the --quiet option passphrase typos will be reported,
   " we must redirect stderr (using shell temporarily)
-  let &shellredir=s:shellredir
-  let &shell=s:shell
+  let &shellredir = s:shellredir
+  let &shell = s:shell
   exec "'[,']!" . s:GPGCommand . " --quiet --decrypt " . s:stderrredirnull
-  let &shellredir=s:shellredirsave
-  let &shell=s:shellsave
+  let &shellredir = s:shellredirsave
+  let &shell = s:shellsave
   if (v:shell_error) " message could not be decrypted
     silent u
     echohl GPGError
-    let asd=input("Message could not be decrypted! (Press ENTER)")
+    let blackhole = input("Message could not be decrypted! (Press ENTER)")
     echohl None
     bwipeout
     set nobin
     return
-  endi
+  endif
 
   " turn off binary mode
   set nobin
@@ -286,26 +346,26 @@
 
   " refresh screen
   redraw!
-endf
+endfunction
 
 " Function: s:GPGEncrypt() {{{2
 "
 " encrypts the buffer to all previous recipients
 "
-fun s:GPGEncrypt()
+function 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
-  if &fileencoding != &encoding
+  if (&fileencoding != &encoding)
     let s:GPGEncoding = &encoding
     let &encoding = &fileencoding
     call s:GPGDebug(2, "encoding was \"" . s:GPGEncoding . "\", switched to \"" . &encoding . "\"")
   else
     let s:GPGEncoding = ""
     call s:GPGDebug(2, "encoding and fileencoding are the same (\"" . &encoding . "\"), not switching")
-  endi
+  endif
 
   " switch buffer to binary mode
   set bin
@@ -313,92 +373,90 @@
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
-
-  let options=""
-  let recipients=""
-  let field=0
+  endif
+
+  " initialize GPGOptions if not happened before
+  if (!exists("b:GPGOptions") || len(b:GPGOptions) == 0)
+    let b:GPGOptions = []
+    if (exists("g:GPGPreferSymmetric") && g:GPGPreferSymmetric == 1)
+      let b:GPGOptions += ["symmetric"]
+      let b:GPGRecipients = []
+    else
+      let b:GPGOptions += ["encrypt"]
+    endif
+    if (exists("g:GPGPreferArmor") && g:GPGPreferArmor == 1)
+      let b:GPGOptions += ["armor"]
+    endif
+    call s:GPGDebug(1, "no options set, so using default options: " . string(b:GPGOptions))
+  endif
 
   " built list of options
-  if (!exists("b:GPGOptions") || strlen(b:GPGOptions) == 0)
-    if (exists("g:GPGPreferSymmetric") && g:GPGPreferSymmetric == 1)
-      let b:GPGOptions="symmetric:"
-    else
-      let b:GPGOptions="encrypt:"
-    endi
-    if (exists("g:GPGPreferArmor") && g:GPGPreferArmor == 1)
-      let b:GPGOptions=b:GPGOptions . "armor:"
-    endi
-    call s:GPGDebug(1, "no options set, so using default options: " . b:GPGOptions)
-  endi
-  let field=0
-  let option=s:GetField(b:GPGOptions, ":", field)
-  while (strlen(option))
-    let options=options . " --" . option . " "
-    let field=field+1
-    let option=s:GetField(b:GPGOptions, ":", field)
-  endw
+  let options = ""
+  for option in b:GPGOptions
+    let options = options . " --" . option . " "
+  endfor
+
+  " check here again if all recipients are available in the keyring
+  let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients)
 
   " check if there are unknown recipients and warn
-  if (exists("b:GPGUnknownRecipients") && strlen(b:GPGUnknownRecipients) > 0)
+  if (len(unknownrecipients) > 0)
     echohl GPGWarning
-    echo "There are unknown recipients!!"
-    echo "Please use GPGEditRecipients to correct!!"
+    echom "Please use GPGEditRecipients to correct!!"
     echo
     echohl None
-    call s:GPGDebug(1, "unknown recipients are: " . b:GPGUnknownRecipients)
-  endi
+
+    " Let user know whats happend and copy known_recipients back to buffer
+    let dummy = input("Press ENTER to quit")
+  endif
 
   " built list of recipients
-  if (exists("b:GPGRecipients") && strlen(b:GPGRecipients) > 0)
-    call s:GPGDebug(1, "recipients are: " . b:GPGRecipients)
-    let field=0
-    let gpgid=s:GetField(b:GPGRecipients, ":", field)
-    while (strlen(gpgid))
-      let recipients=recipients . " -r " . gpgid
-      let field=field+1
-      let gpgid=s:GetField(b:GPGRecipients, ":", field)
-    endw
+  if (len(recipients) > 0)
+    for gpgid in recipients
+      let options = options . " -r " . gpgid
+    endfor
   else
-    if (match(b:GPGOptions, "encrypt:") >= 0)
+    if (match(b:GPGOptions, "encrypt") >= 0)
       echohl GPGError
-      echo "There are no recipients!!"
-      echo "Please use GPGEditRecipients to correct!!"
+      echom "There are no recipients!!"
+      echom "Please use GPGEditRecipients to correct!!"
       echo
       echohl None
-    endi
-  endi
+    endif
+  endif
 
   " encrypt the buffer
-  let &shellredir=s:shellredir
-  let &shell=s:shell
-  silent exec "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . recipients . " " . s:stderrredirnull
-  let &shellredir=s:shellredirsave
-  let &shell=s:shellsave
-  call s:GPGDebug(1, "called gpg command is: " . "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . recipients . " " . s:stderrredirnull)
+  let &shellredir = s:shellredir
+  let &shell = s:shell
+  silent exec "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . " " . s:stderrredirnull
+  let &shellredir = s:shellredirsave
+  let &shell = s:shellsave
+  call s:GPGDebug(1, "called gpg command is: " . "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . " " . s:stderrredirnull)
   if (v:shell_error) " message could not be encrypted
-    silent u
+    " 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 asd=input("Message could not be encrypted! File might be empty! (Press ENTER)")
-    echohl None
-    bwipeout
+    let blackhole = input("Message could not be encrypted! File might be empty! (Press ENTER)")
+    echohl None
     return
-  endi
-
-endf
+  endif
+
+endfunction
 
 " Function: s:GPGEncryptPost() {{{2
 "
 " undo changes don by encrypt, after writing
 "
-fun s:GPGEncryptPost()
-
+function s:GPGEncryptPost()
+  " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     return
-  endi
+  endif
 
   " undo encryption of buffer content
   silent u
@@ -407,10 +465,10 @@
   set nobin
 
   " restore encoding
-  if s:GPGEncoding != ""
+  if (s:GPGEncoding != "")
     let &encoding = s:GPGEncoding
     call s:GPGDebug(2, "restored encoding \"" . &encoding . "\"")
-  endi
+  endif
 
   " restore window view
   call winrestview(s:GPGWindowView)
@@ -418,108 +476,99 @@
 
   " refresh screen
   redraw!
-endf
+endfunction
 
 " Function: s:GPGViewRecipients() {{{2
 "
 " echo the recipients
 "
-fun s:GPGViewRecipients()
+function s:GPGViewRecipients()
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
-
-  if (exists("b:GPGRecipients"))
-    echo 'This file has following recipients (Unknown recipients have a prepended "!"):'
-    " echo the recipients
-    let field=0
-    let name=s:GetField(b:GPGRecipients, ":", field)
-    while (strlen(name) > 0)
-      let name=s:GPGIDToName(name)
-      echo name
-
-      let field=field+1
-      let name=s:GetField(b:GPGRecipients, ":", field)
-    endw
-
-    " put the unknown recipients in the scratch buffer
-    let field=0
-    echohl GPGWarning
-    let name=s:GetField(b:GPGUnknownRecipients, ":", field)
-    while (strlen(name) > 0)
-      let name="!" . name
-      echo name
-
-      let field=field+1
-      let name=s:GetField(b:GPGUnknownRecipients, ":", field)
-    endw
-    echohl None
-
-    " check if there is any known recipient
-    if (strlen(s:GetField(b:GPGRecipients, ":", 0)) == 0)
-      echohl GPGError
-      echo 'There are no known recipients!'
-      echohl None
-    endi
-  endi
-endf
+  endif
+
+  let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients)
+
+  echo 'This file has following recipients (Unknown recipients have a prepended "!"):'
+  " echo the recipients
+  for name in recipients
+    let name = s:GPGIDToName(name)
+    echo name
+  endfor
+
+  " echo the unknown recipients
+  echohl GPGWarning
+  for name in unknownrecipients
+    let name = "!" . name
+    echo name
+  endfor
+  echohl None
+
+  " check if there is any known recipient
+  if (len(recipients) == 0)
+    echohl GPGError
+    echom 'There are no known recipients!'
+    echohl None
+  endif
+endfunction
 
 " Function: s:GPGEditRecipients() {{{2
 "
 " create a scratch buffer with all recipients to add/remove recipients
 "
-fun s:GPGEditRecipients()
+function s:GPGEditRecipients()
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
+  endif
 
   " only do this if it isn't already a GPGRecipients_* buffer
   if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0)
 
     " save buffer name
-    let buffername=bufname("%")
-    let editbuffername="GPGRecipients_" . buffername
+    let buffername = bufname("%")
+    let editbuffername = "GPGRecipients_" . buffername
 
     " check if this buffer exists
     if (!bufexists(editbuffername))
       " create scratch buffer
-      exe 'silent! split ' . escape(editbuffername, ' *?\"'."'")
+      execute 'silent! split ' . escape(editbuffername, ' *?\"'."'")
 
       " add a autocommand to regenerate the recipients after a write
-      autocmd BufHidden,BufUnload <buffer> call s:GPGFinishRecipientsBuffer()
+      autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishRecipientsBuffer()
     else
       if (bufwinnr(editbuffername) >= 0)
-	" switch to scratch buffer window
-	exe 'silent! ' . bufwinnr(editbuffername) . "wincmd w"
+        " switch to scratch buffer window
+        execute '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
+        " split scratch buffer window
+        execute 'silent! sbuffer ' . escape(editbuffername, ' *?\"'."'")
+
+        " add a autocommand to regenerate the recipients after a write
+        autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishRecipientsBuffer()
+      endif
 
       " empty the buffer
       silent normal! 1GdG
-    endi
+    endif
 
     " Mark the buffer as a scratch buffer
-    setlocal buftype=nofile
+    setlocal buftype=acwrite
+    setlocal bufhidden=hide
     setlocal noswapfile
     setlocal nowrap
     setlocal nobuflisted
     setlocal nonumber
 
     " so we know for which other buffer this edit buffer is
-    let b:corresponding_to=buffername
+    let b:GPGCorrespondingTo = buffername
 
     " put some comments to the scratch buffer
     silent put ='GPG: ----------------------------------------------------------------------'
@@ -529,35 +578,34 @@
     silent put ='GPG: Closing this buffer commits changes'
     silent put ='GPG: ----------------------------------------------------------------------'
 
+    " get the recipients
+    let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(getbufvar(b:GPGCorrespondingTo, "GPGRecipients"))
+
+    " if there are no known or unknown recipients, use the default ones
+    if (len(recipients) == 0 && len(unknownrecipients) == 0)
+      if (type(g:GPGDefaultRecipients) == type([]))
+        let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(g:GPGDefaultRecipients)
+      else
+        echohl GPGWarning
+        echom "g:GPGDefaultRecipients is not a Vim list, please correct this in your vimrc!"
+        echohl None
+      endif
+    endif
+
     " put the recipients in the scratch buffer
-    let recipients=getbufvar(b:corresponding_to, "GPGRecipients")
-    let field=0
-
-    let name=s:GetField(recipients, ":", field)
-    while (strlen(name) > 0)
-      let name=s:GPGIDToName(name)
+    for name in recipients
+      let name = s:GPGIDToName(name)
       silent put =name
-
-      let field=field+1
-      let name=s:GetField(recipients, ":", field)
-    endw
+    endfor
 
     " put the unknown recipients in the scratch buffer
-    let unknownRecipients=getbufvar(b:corresponding_to, "GPGUnknownRecipients")
-    let field=0
-    let syntaxPattern="\\(nonexistingwordinthisbuffer"
-
-    let name=s:GetField(unknownRecipients, ":", field)
-    while (strlen(name) > 0)
-      let name="!" . name
-      let syntaxPattern=syntaxPattern . "\\|" . name
+    let syntaxPattern = "\\(nonexxistinwordinthisbuffer"
+    for name in unknownrecipients
+      let name = "!" . name
+      let syntaxPattern = syntaxPattern . "\\|" . name
       silent put =name
-
-      let field=field+1
-      let name=s:GetField(unknownRecipients, ":", field)
-    endw
-
-    let syntaxPattern=syntaxPattern . "\\)"
+    endfor
+    let syntaxPattern = syntaxPattern . "\\)"
 
     " define highlight
     if (has("syntax") && exists("g:syntax_on"))
@@ -568,7 +616,7 @@
       syntax match GPGComment "^GPG:.*$"
       highlight clear GPGComment
       highlight link GPGComment Comment
-    endi
+    endif
 
     " delete the empty first line
     silent normal! 1Gdd
@@ -576,146 +624,140 @@
     " jump to the first recipient
     silent normal! G
 
-  endi
-endf
+  endif
+endfunction
 
 " Function: s:GPGFinishRecipientsBuffer() {{{2
 "
 " create a new recipient list from RecipientsBuffer
-fun s:GPGFinishRecipientsBuffer()
+function s:GPGFinishRecipientsBuffer()
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
+  endif
 
   " 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
-  let GPGRecipients=""
-  let GPGUnknownRecipients=""
+    execute 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w"
+  endif
 
   " delete the autocommand
   autocmd! * <buffer>
 
-  let currentline=1
-  let recipient=getline(currentline)
 
   " get the recipients 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 recipient=substitute(recipient, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "")
+  let recipients = []
+  let lines = getline(1,"$")
+  for recipient in lines
+    " delete all spaces at beginning and end of the recipient
+    " also delete a '!' at the beginning of the recipient
+    let recipient = substitute(recipient, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "")
     " delete comment lines
-    let recipient=substitute(recipient, "^GPG:.*$", "", "")
+    let recipient = substitute(recipient, "^GPG:.*$", "", "")
 
     " only do this if the line is not empty
     if (strlen(recipient) > 0)
-      let gpgid=s:GPGNameToID(recipient)
+      let gpgid = s:GPGNameToID(recipient)
       if (strlen(gpgid) > 0)
-	let GPGRecipients=GPGRecipients . gpgid . ":" 
+        if (match(recipients, gpgid) < 0)
+          let recipients += [gpgid]
+        endif
       else
-	let GPGUnknownRecipients=GPGUnknownRecipients . recipient . ":"
-	echohl GPGWarning
-	echo "The recipient " . recipient . " is not in your public keyring!"
-	echohl None
-      end
-    endi
-
-    let currentline=currentline+1
-    let recipient=getline(currentline)
-  endw
+        if (match(recipients, recipient) < 0)
+          let recipients += [recipient]
+          echohl GPGWarning
+          echom "The recipient \"" . recipient . "\" is not in your public keyring!"
+          echohl None
+        endif
+      endif
+    endif
+  endfor
 
   " write back the new recipient list to the corresponding buffer and mark it
   " as modified. Buffer is now for sure a encrypted buffer.
-  call setbufvar(b:corresponding_to, "GPGRecipients", GPGRecipients)
-  call setbufvar(b:corresponding_to, "GPGUnknownRecipients", GPGUnknownRecipients)
-  call setbufvar(b:corresponding_to, "&mod", 1)
-  call setbufvar(b:corresponding_to, "GPGEncrypted", 1)
+  call setbufvar(b:GPGCorrespondingTo, "GPGRecipients", recipients)
+  call setbufvar(b:GPGCorrespondingTo, "&mod", 1)
+  call setbufvar(b:GPGCorrespondingTo, "GPGEncrypted", 1)
 
   " check if there is any known recipient
-  if (strlen(s:GetField(GPGRecipients, ":", 0)) == 0)
+  if (len(recipients) == 0)
     echohl GPGError
-    echo 'There are no known recipients!'
-    echohl None
-  endi
-endf
+    echom 'There are no known recipients!'
+    echohl None
+  endif
+
+  " reset modified flag
+  set nomodified
+endfunction
 
 " Function: s:GPGViewOptions() {{{2
 "
 " echo the recipients
 "
-fun s:GPGViewOptions()
+function s:GPGViewOptions()
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
+  endif
 
   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)
+    for option in b:GPGOptions
       echo option
-
-      let field=field+1
-      let option=s:GetField(b:GPGOptions, ":", field)
-    endw
-  endi
-endf
+    endfor
+  endif
+endfunction
 
 " Function: s:GPGEditOptions() {{{2
 "
 " create a scratch buffer with all recipients to add/remove recipients
 "
-fun s:GPGEditOptions()
+function s:GPGEditOptions()
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
+  endif
 
   " 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
+    let buffername = bufname("%")
+    let editbuffername = "GPGOptions_" . buffername
 
     " check if this buffer exists
     if (!bufexists(editbuffername))
       " create scratch buffer
-      exe 'silent! split ' . escape(editbuffername, ' *?\"'."'")
+      execute 'silent! split ' . escape(editbuffername, ' *?\"'."'")
 
       " add a autocommand to regenerate the options after a write
-      autocmd BufHidden,BufUnload <buffer> call s:GPGFinishOptionsBuffer()
+      autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishOptionsBuffer()
     else
       if (bufwinnr(editbuffername) >= 0)
-	" switch to scratch buffer window
-	exe 'silent! ' . bufwinnr(editbuffername) . "wincmd w"
+        " switch to scratch buffer window
+        execute '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
+        " split scratch buffer window
+        execute 'silent! sbuffer ' . escape(editbuffername, ' *?\"'."'")
+
+        " add a autocommand to regenerate the options after a write
+        autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishOptionsBuffer()
+      endif
 
       " empty the buffer
       silent normal! 1GdG
-    endi
+    endif
 
     " Mark the buffer as a scratch buffer
     setlocal buftype=nofile
@@ -725,7 +767,7 @@
     setlocal nonumber
 
     " so we know for which other buffer this edit buffer is
-    let b:corresponding_to=buffername
+    let b:GPGCorrespondingTo = buffername
 
     " put some comments to the scratch buffer
     silent put ='GPG: ----------------------------------------------------------------------'
@@ -739,16 +781,11 @@
     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)
+    let options = getbufvar(b:GPGCorrespondingTo, "GPGOptions")
+
+    for option in options
       silent put =option
-
-      let field=field+1
-      let option=s:GetField(options, ":", field)
-    endw
+    endfor
 
     " delete the empty first line
     silent normal! 1Gdd
@@ -761,207 +798,218 @@
       syntax match GPGComment "^GPG:.*$"
       highlight clear GPGComment
       highlight link GPGComment Comment
-    endi
-  endi
-endf
+    endif
+  endif
+endfunction
 
 " Function: s:GPGFinishOptionsBuffer() {{{2
 "
 " create a new option list from OptionsBuffer
-fun s:GPGFinishOptionsBuffer()
+function s:GPGFinishOptionsBuffer()
   " guard for unencrypted files
   if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0)
     echohl GPGWarning
-    echo "File is not encrypted, all GPG functions disabled!"
+    echom "File is not encrypted, all GPG functions disabled!"
     echohl None
     return
-  endi
+  endif
 
   " 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=""
+    execute 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w"
+  endif
+
+  " clear options and unknownOptions
+  let options = []
+  let unknownOptions = []
 
   " 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", "")
+  let lines = getline(1, "$")
+  for option in lines
+    " delete all spaces at beginning and end of the option
+    " also delete a '!' at the beginning of the option
+    let option = substitute(option, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "")
     " delete comment lines
-    let option=substitute(option, "^GPG:.*$", "", "")
+    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
+    if (strlen(option) > 0 && match(options, option) < 0)
+      let options += [option]
+    endif
+  endfor
 
   " 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
+  call setbufvar(b:GPGCorrespondingTo, "GPGOptions", options)
+  call setbufvar(b:GPGCorrespondingTo, "&mod", 1)
+
+  " reset modified flag
+  set nomodified
+endfunction
+
+" Function: s:GPGCheckRecipients(tocheck) {{{2
+"
+" check if recipients are known
+" Returns: two lists recipients and unknownrecipients
+function s:GPGCheckRecipients(tocheck)
+  let recipients = []
+  let unknownrecipients = []
+
+  if (type(a:tocheck) == type([]))
+    for recipient in a:tocheck
+      let gpgid = s:GPGNameToID(recipient)
+      if (strlen(gpgid) > 0)
+        if (match(recipients, gpgid) < 0)
+          let recipients += [gpgid]
+        endif
+      else
+        if (match(unknownrecipients, recipient) < 0)
+          let unknownrecipients += [recipient]
+          echohl GPGWarning
+          echom "The recipient \"" . recipient . "\" is not in your public keyring!"
+          echohl None
+        endif
+      end
+    endfor
+  endif
+
+  call s:GPGDebug(2, "recipients are: " . string(recipients))
+  call s:GPGDebug(2, "unknown recipients are: " . string(unknownrecipients))
+
+  return [ recipients, unknownrecipients ]
+endfunction
 
 " Function: s:GPGNameToID(name) {{{2
 "
 " find GPG key ID corresponding to a name
 " Returns: ID for the given name
-fun s:GPGNameToID(name)
+function s:GPGNameToID(name)
   " ask gpg for the id for 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:shellredirsave
-  let &shell=s:shellsave
+  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:shellredirsave
+  let &shell = s:shellsave
+
+  " when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8,
+  " so convert it, if necessary
+  if (&encoding != "utf-8")
+    let output = iconv(output, "utf-8", &encoding)
+  endif
+  let lines = split(output, "\n")
 
   " parse the output of gpg
-  let pub_seen=0
-  let uid_seen=0
-  let line=0
-  let counter=0
-  let gpgids=""
-  let choices="The name \"" . a:name . "\" is ambiguous. Please select the correct key:\n"
-  let linecontent=s:GetField(output, "\n", line)
-  while (strlen(linecontent))
+  let pubseen = 0
+  let uidseen = 0
+  let counter = 0
+  let gpgids = []
+  let choices = "The name \"" . a:name . "\" is ambiguous. Please select the correct key:\n"
+  for line in lines
+    let fields = split(line, ":")
     " search for the next uid
-    if (pub_seen == 1)
-      if (s:GetField(linecontent, ":", 0) == "uid")
-	if (uid_seen == 0)
-	  let choices=choices . counter . ": " . s:GetField(linecontent, ":", 9) . "\n"
-	  let counter=counter+1
-	  let uid_seen=1
-	else
-	  let choices=choices . "   " . s:GetField(linecontent, ":", 9) . "\n"
-	endi
+    if (pubseen == 1)
+      if (fields[0] == "uid")
+        if (uidseen == 0)
+          let choices = choices . counter . ": " . fields[9] . "\n"
+          let counter = counter+1
+          let uidseen = 1
+        else
+          let choices = choices . "   " . fields[9] . "\n"
+        endif
       else
-	let uid_seen=0
-	let pub_seen=0
-      endi
-    endi
+        let uidseen = 0
+        let pubseen = 0
+      endif
+    endif
 
     " search for the next pub
-    if (pub_seen == 0)
-      if (s:GetField(linecontent, ":", 0) == "pub")
-	let gpgids=gpgids . s:GetField(linecontent, ":", 4) . ":"
-	let pub_seen=1
-      endi
-    endi
-
-    let line=line+1
-    let linecontent=s:GetField(output, "\n", line)
-  endw
+    if (pubseen == 0)
+      if (fields[0] == "pub")
+        let gpgids += [fields[4]]
+        let pubseen = 1
+      endif
+    endif
+
+  endfor
 
   " counter > 1 means we have more than one results
-  let answer=0
+  let answer = 0
   if (counter > 1)
-    let choices=choices . "Enter number: "
-    let answer=input(choices, "0")
+    let choices = choices . "Enter number: "
+    let answer = input(choices, "0")
     while (answer == "")
-      let answer=input("Enter number: ", "0")
-    endw
-  endi
-
-  return s:GetField(gpgids, ":", answer)
-endf
+      let answer = input("Enter number: ", "0")
+    endwhile
+  endif
+
+  return get(gpgids, answer, "")
+endfunction
 
 " Function: s:GPGIDToName(identity) {{{2
 "
 " find name corresponding to a GPG key ID
 " Returns: Name for the given ID
-fun s:GPGIDToName(identity)
+function s:GPGIDToName(identity)
   " TODO is the encryption subkey really unique?
 
   " ask gpg for the id for a name
-  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:shellredirsave
-  let &shell=s:shellsave
+  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:shellredirsave
+  let &shell = s:shellsave
+
+  " when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8,
+  " so convert it, if necessary
+  if (&encoding != "utf-8")
+    let output = iconv(output, "utf-8", &encoding)
+  endif
+  let lines = split(output, "\n")
 
   " parse the output of gpg
-  let pub_seen=0
-  let finish=0
-  let line=0
-  let linecontent=s:GetField(output, "\n", line)
-  while (strlen(linecontent) && !finish)
-    if (pub_seen == 0) " search for the next pub
-      if (s:GetField(linecontent, ":", 0) == "pub")
-	let pub_seen=1
-      endi
+  let pubseen = 0
+  let uid = ""
+  for line in lines
+    let fields = split(line, ":")
+    if (pubseen == 0) " search for the next pub
+      if (fields[0] == "pub")
+        let pubseen = 1
+      endif
     else " search for the next uid
-      if (s:GetField(linecontent, ":", 0) == "uid")
-	let pub_seen=0
-	let finish=1
-	let uid=s:GetField(linecontent, ":", 9)
-      endi
-    endi
-
-    let line=line+1
-    let linecontent=s:GetField(output, "\n", line)
-  endw
+      if (fields[0] == "uid")
+        let pubseen = 0
+        let uid = fields[9]
+        break
+      endif
+    endif
+  endfor
 
   return uid
-endf
-
-" Function: s:GetField(line, separator, field) {{{2
-"
-" find field of 'separator' separated string, counting starts with 0
-" Returns: content of the field, if field doesn't exist it returns an empty
-"          string
-fun s:GetField(line, separator, field)
-  let counter=a:field
-  let separatorLength=strlen(a:separator)
-  let start=0
-  let end=match(a:line, a:separator)
-  if (end < 0)
-    let end=strlen(a:line)
-  endi
-
-  " search for requested field
-  while (start < strlen(a:line) && counter > 0)
-    let counter=counter-separatorLength
-    let start=end+separatorLength
-    let end=match(a:line, a:separator, start)
-    if (end < 0)
-      let end=strlen(a:line)
-    endi
-  endw
-
-  if (start < strlen(a:line))
-    return strpart(a:line, start, end-start)
-  else
-    return ""
-  endi
-endf
+endfunction
 
 " Function: s:GPGDebug(level, text) {{{2
 "
 " output debug message, if this message has high enough importance
-fun s:GPGDebug(level, text)
+function s:GPGDebug(level, text)
   if (g:GPGDebugLevel >= a:level)
     echom a:text
-  endi
-endf
+  endif
+endfunction
 
 " Section: Command definitions {{{1
-com! GPGViewRecipients call s:GPGViewRecipients()
-com! GPGEditRecipients call s:GPGEditRecipients()
-com! GPGViewOptions call s:GPGViewOptions()
-com! GPGEditOptions call s:GPGEditOptions()
-
+command! GPGViewRecipients call s:GPGViewRecipients()
+command! GPGEditRecipients call s:GPGEditRecipients()
+command! GPGViewOptions call s:GPGViewOptions()
+command! GPGEditOptions call s:GPGEditOptions()
+" Section: Menu {{{1
+if (has("menu"))
+  amenu <silent> Plugin.GnuPG.View\ Recipients :GPGViewRecipients<CR>
+  amenu <silent> Plugin.GnuPG.Edit\ Recipients :GPGEditRecipients<CR>
+  amenu <silent> Plugin.GnuPG.View\ Options :GPGViewOptions<CR>
+  amenu <silent> Plugin.GnuPG.Edit\ Options :GPGEditOptions<CR>
+endif
 " vim600: foldmethod=marker:foldlevel=0




More information about the pkg-vim-maintainers mailing list