Vim Tips Wiki
Advertisement
Tip 651 Printable Monobook Previous Next

created February 5, 2004 · complexity intermediate · author Frank Price · version 6.0


It can be somewhat laborious to edit a file which you have encrypted: first you have to decrypt to plaintext, then use Vim and save; then encrypt again. The method below lets Vim take care of some of the dirty work.

First, be sure you have gnupg setup to the point where you can ascii-armor encrypt a file using your own public key, and decrypt it again.

Then put this into your vimrc (don't duplicate the 'if has("autocmd")' part if it is already there):

if has("autocmd")
  augroup GPGASCII
    au!
    au BufReadPost *.asc :%!gpg -q -d
    au BufReadPost *.asc |redraw
    au BufWritePre *.asc :%!gpg -q -e -a
    au BufWritePost *.asc u
    au VimLeave *.asc :!clear
  augroup END
endif " has ("autocmd")

You might also want to add these options to your ~/.gnupg/options file to decrease the messages that gnupg outputs:

no-greeting
quiet
default-recipient-self #to always encrypt for yourself.

Now Vim a new file, the name of which ends with .asc:

vim important.asc

and edit. When you save and quit, gnupg may prompt for gnupg ids to encrypt for (if you don't have default-recipient-self set). Enter your own. To edit, just Vim it again and you'll be prompted for your passphrase.

This isn't perfect -- in particular, you occasionally have to tell Vim to redraw with ctrl-L to get rid of gnupg crud -- but it works pretty well for me.

Comments[]

One should be aware of leaving pieces of the plaintext inside registers in .viminfo file.


Specify -n option, so that Vim doesn't use swap file and save the plain text to disk.

I wrote the vimcrypt functionality in vim5.7 when I was in India, it's not strong, but keeps the grandmons and admin at bay.


When I do a :w the cursor position is reset to the beginning of the buffer.


If gpg fails, your encrypted file is gone.


Call it with

vim -i NONE -n file.gpg

so no viminfo will be read/written and no swap file plaintext copy will be made.


A small addition - If you type your password wrong, you'll get the "incorrect password" message in the buffer. By adding '2> /dev/null' to the 'au BufReadPost *.asc :%!gpg -q -d' line, those error messages won't show up.


Here is a bit more complicated script for this GPG integration. (~/.vimrc of my machine) which uses Wooter's code. A bit more consideration to back up files etc.

" Local configuration
set nocompatible
set nopaste
set pastetoggle=<F11>
syn on
set runtimepath=~/.vim,/etc/vim,/usr/share/vim/vimfiles
set runtimepath+=/usr/share/vim/addons,/usr/share/vim/vim61
set runtimepath+=/usr/share/vim/vimfiles/after,~/.vim/after

" Transparent editing of gpg encrypted files.
" Placed Public Domain by Wouter Hanegraaff
" (asc support and sh -c"..." added by Osamu Aoki)
augroup aencrypted
  au!
  " First make sure nothing is written to ~/.viminfo while editing
  " an encrypted file.
  autocmd BufReadPre,FileReadPre *.asc set viminfo=
  " We don't want a swap file, as it writes unencrypted data to disk
  autocmd BufReadPre,FileReadPre *.asc set noswapfile
  " Switch to binary mode to read the encrypted file
  autocmd BufReadPre,FileReadPre *.asc set bin
  autocmd BufReadPre,FileReadPre *.asc let ch_save = &ch|set ch=2
  autocmd BufReadPost,FileReadPost *.asc '[,']!sh -c "gpg --decrypt 2> /dev/null"
  " Switch to normal mode for editing
  autocmd BufReadPost,FileReadPost *.asc set nobin
  autocmd BufReadPost,FileReadPost *.asc let &ch = ch_save|unlet ch_save
  autocmd BufReadPost,FileReadPost *.asc execute ":doautocmd BufReadPost " . expand("%:r")

  " Convert all text to encrypted text before writing
  autocmd BufWritePre,FileWritePre *.asc '[,']!sh -c "gpg --default-recipient-self -ae 2>/dev/null"
  " Undo the encryption so we are back in the normal text, directly
  " after the file has been written.
  autocmd BufWritePost,FileWritePost *.asc u
augroup END
augroup bencrypted
  au!
  " First make sure nothing is written to ~/.viminfo while editing
  " an encrypted file.
  autocmd BufReadPre,FileReadPre *.gpg set viminfo=
  " We don't want a swap file, as it writes unencrypted data to disk
  autocmd BufReadPre,FileReadPre *.gpg set noswapfile
  " Switch to binary mode to read the encrypted file
  autocmd BufReadPre,FileReadPre *.gpg set bin
  autocmd BufReadPre,FileReadPre *.gpg let ch_save = &ch|set ch=2
  autocmd BufReadPost,FileReadPost *.gpg '[,']!sh -c "gpg --decrypt 2> /dev/null"
  " Switch to normal mode for editing
  autocmd BufReadPost,FileReadPost *.gpg set nobin
  autocmd BufReadPost,FileReadPost *.gpg let &ch = ch_save|unlet ch_save
  autocmd BufReadPost,FileReadPost *.gpg execute ":doautocmd BufReadPost " . expand("%:r")

  " Convert all text to encrypted text before writing
  autocmd BufWritePre,FileWritePre *.gpg '[,']!sh -c "gpg --default-recipient-self -e 2>/dev/null"
  " Undo the encryption so we are back in the normal text, directly
  " after the file has been written.
  autocmd BufWritePost,FileWritePost *.gpg u
augroup END

Before writing *gpg, why don't you need to "set bin"?

(and "set nobin" after writing)


This script is great! script#661 I just wish I could use *.asc files as well as *.gpg files. All you have to do is rename the file to change the extension, so it not to big of an issue.


In the above script (script#661), there is a fold "Section: Autocmd setup".

In that section you can add/change the extensions you like. For example I added *.pgp:

autocmd .... *.\(gpg\|pgp\) ...

Advertisement