Mercurial > index.cgi > dotfiles
comparison .vim/plugin/gnupg.vim @ 41:2bea356b1032
* Added default screenrc from Linux (and the Screen installation) to .screenrc
* Brought ~/.vim into repository (some syntax hilighting add-ons, gnupg
plugin)
* Hard-coded paths for aliases so as not to conflict with GNU coreutils from a
Macports install
* Removed dvra alias
* Added $VNCVIEWER and changed VNC-type aliases to use it
* Added syrinx aliases
* Added syrinx to toodledo targets
author | huston@80426f53-59d1-405d-934b-f07cd76f4a1a |
---|---|
date | Thu, 17 Jun 2010 16:29:11 +0000 |
parents | |
children | fa4f783acc35 |
comparison
equal
deleted
inserted
replaced
40:21cf7b5fa0d6 | 41:2bea356b1032 |
---|---|
1 " Name: gnupg.vim | |
2 " Version: $Id: gnupg.vim 3026 2010-01-27 08:18:04Z mbr $ | |
3 " Author: Markus Braun <markus.braun@krawel.de> | |
4 " Summary: Vim plugin for transparent editing of gpg encrypted files. | |
5 " Licence: This program is free software; you can redistribute it and/or | |
6 " modify it under the terms of the GNU General Public License. | |
7 " See http://www.gnu.org/copyleft/gpl.txt | |
8 " | |
9 " Section: Documentation {{{1 | |
10 " | |
11 " Description: {{{2 | |
12 " | |
13 " This script implements transparent editing of gpg encrypted files. The | |
14 " filename must have a ".gpg", ".pgp" or ".asc" suffix. When opening such | |
15 " a file the content is decrypted, when opening a new file the script will | |
16 " ask for the recipients of the encrypted file. The file content will be | |
17 " encrypted to all recipients before it is written. The script turns off | |
18 " viminfo and swapfile to increase security. | |
19 " | |
20 " Installation: {{{2 | |
21 " | |
22 " Copy the gnupg.vim file to the $HOME/.vim/plugin directory. | |
23 " Refer to ':help add-plugin', ':help add-global-plugin' and ':help | |
24 " runtimepath' for more details about Vim plugins. | |
25 " | |
26 " From "man 1 gpg-agent": | |
27 " | |
28 " ... | |
29 " You should always add the following lines to your .bashrc or whatever | |
30 " initialization file is used for all shell invocations: | |
31 " | |
32 " GPG_TTY=`tty` | |
33 " export GPG_TTY | |
34 " | |
35 " It is important that this environment variable always reflects the out‐ | |
36 " put of the tty command. For W32 systems this option is not required. | |
37 " ... | |
38 " | |
39 " Most distributions provide software to ease handling of gpg and gpg-agent. | |
40 " Examples are keychain or seahorse. | |
41 " | |
42 " Commands: {{{2 | |
43 " | |
44 " :GPGEditRecipients | |
45 " Opens a scratch buffer to change the list of recipients. Recipients that | |
46 " are unknown (not in your public key) are highlighted and have | |
47 " a prepended "!". Closing the buffer makes the changes permanent. | |
48 " | |
49 " :GPGViewRecipients | |
50 " Prints the list of recipients. | |
51 " | |
52 " :GPGEditOptions | |
53 " Opens a scratch buffer to change the options for encryption (symmetric, | |
54 " asymmetric, signing). Closing the buffer makes the changes permanent. | |
55 " WARNING: There is no check of the entered options, so you need to know | |
56 " what you are doing. | |
57 " | |
58 " :GPGViewOptions | |
59 " Prints the list of options. | |
60 " | |
61 " Variables: {{{2 | |
62 " | |
63 " g:GPGExecutable | |
64 " If set used as gpg executable, otherwise the system chooses what is run | |
65 " when "gpg" is called. Defaults to "gpg". | |
66 " | |
67 " g:GPGUseAgent | |
68 " If set to 0 a possible available gpg-agent won't be used. Defaults to 1. | |
69 " | |
70 " g:GPGPreferSymmetric | |
71 " If set to 1 symmetric encryption is preferred for new files. Defaults to 0. | |
72 " | |
73 " g:GPGPreferArmor | |
74 " If set to 1 armored data is preferred for new files. Defaults to 0. | |
75 " | |
76 " g:GPGPreferSign | |
77 " If set to 1 signed data is preferred for new files. Defaults to 0. | |
78 " | |
79 " g:GPGDefaultRecipients | |
80 " If set, these recipients are used as defaults when no other recipient is | |
81 " defined. This variable is a Vim list. Default is unset. | |
82 " | |
83 " Known Issues: {{{2 | |
84 " | |
85 " In some cases gvim can't decryt files | |
86 | |
87 " This is caused by the fact that a running gvim has no TTY and thus gpg is | |
88 " not able to ask for the passphrase by itself. This is a problem for Windows | |
89 " and Linux versions of gvim and could not be solved unless a "terminal | |
90 " emulation" is implemented for gvim. To circumvent this you have to use any | |
91 " combination of gpg-agent and a graphical pinentry program: | |
92 " | |
93 " - gpg-agent only: | |
94 " you need to provide the passphrase for the needed key to gpg-agent | |
95 " in a terminal before you open files with gvim which require this key. | |
96 " | |
97 " - pinentry only: | |
98 " you will get a popup window every time you open a file that needs to | |
99 " be decrypted. | |
100 " | |
101 " - gpgagent and pinentry: | |
102 " you will get a popup window the first time you open a file that | |
103 " needs to be decrypted. | |
104 " | |
105 " Credits: {{{2 | |
106 " | |
107 " - Mathieu Clabaut for inspirations through his vimspell.vim script. | |
108 " - Richard Bronosky for patch to enable ".pgp" suffix. | |
109 " - Erik Remmelzwaal for patch to enable windows support and patient beta | |
110 " testing. | |
111 " - Lars Becker for patch to make gpg2 working. | |
112 " - Thomas Arendsen Hein for patch to convert encoding of gpg output | |
113 " - Karl-Heinz Ruskowski for patch to fix unknown recipients and trust model | |
114 " and patient beta testing. | |
115 " - Giel van Schijndel for patch to get GPG_TTY dynamically. | |
116 " - Sebastian Luettich for patch to fix issue with symmetric encryption an set | |
117 " recipients. | |
118 " - Tim Swast for patch to generate signed files | |
119 " | |
120 " Section: Plugin header {{{1 | |
121 | |
122 " guard against multiple loads {{{2 | |
123 if (exists("g:loaded_gnupg") || &cp || exists("#BufReadPre#*.\(gpg\|asc\|pgp\)")) | |
124 finish | |
125 endif | |
126 let g:loaded_gnupg = "$Revision: 3026 $" | |
127 | |
128 " check for correct vim version {{{2 | |
129 if (v:version < 700) | |
130 echohl ErrorMsg | echo 'plugin gnupg.vim requires Vim version >= 7.0' | echohl None | |
131 finish | |
132 endif | |
133 | |
134 " Section: Autocmd setup {{{1 | |
135 | |
136 augroup GnuPG | |
137 autocmd! | |
138 | |
139 " initialize the internal variables | |
140 autocmd BufNewFile,BufReadPre,FileReadPre *.\(gpg\|asc\|pgp\) call s:GPGInit() | |
141 " force the user to edit the recipient list if he opens a new file and public | |
142 " keys are preferred | |
143 autocmd BufNewFile *.\(gpg\|asc\|pgp\) if (exists("g:GPGPreferSymmetric") && g:GPGPreferSymmetric == 0) | call s:GPGEditRecipients() | endif | |
144 " do the decryption | |
145 autocmd BufReadPost,FileReadPost *.\(gpg\|asc\|pgp\) call s:GPGDecrypt() | |
146 | |
147 " convert all text to encrypted text before writing | |
148 autocmd BufWritePre,FileWritePre *.\(gpg\|asc\|pgp\) call s:GPGEncrypt() | |
149 " undo the encryption so we are back in the normal text, directly | |
150 " after the file has been written. | |
151 autocmd BufWritePost,FileWritePost *.\(gpg\|asc\|pgp\) call s:GPGEncryptPost() | |
152 | |
153 " cleanup on leaving vim | |
154 autocmd VimLeave *.\(gpg\|asc\|pgp\) call s:GPGCleanup() | |
155 augroup END | |
156 | |
157 " Section: Constants {{{1 | |
158 | |
159 let s:GPGMagicString = "\t \t" | |
160 | |
161 " Section: Highlight setup {{{1 | |
162 | |
163 highlight default link GPGWarning WarningMsg | |
164 highlight default link GPGError ErrorMsg | |
165 highlight default link GPGHighlightUnknownRecipient ErrorMsg | |
166 | |
167 " Section: Functions {{{1 | |
168 | |
169 " Function: s:GPGInit() {{{2 | |
170 " | |
171 " initialize the plugin | |
172 " | |
173 function s:GPGInit() | |
174 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGInit()") | |
175 | |
176 " first make sure nothing is written to ~/.viminfo while editing | |
177 " an encrypted file. | |
178 set viminfo= | |
179 | |
180 " we don't want a swap file, as it writes unencrypted data to disk | |
181 set noswapfile | |
182 | |
183 " check what gpg command to use | |
184 if (!exists("g:GPGExecutable")) | |
185 let g:GPGExecutable = "gpg --trust-model always" | |
186 endif | |
187 | |
188 " check if gpg-agent is allowed | |
189 if (!exists("g:GPGUseAgent")) | |
190 let g:GPGUseAgent = 1 | |
191 endif | |
192 | |
193 " check if symmetric encryption is preferred | |
194 if (!exists("g:GPGPreferSymmetric")) | |
195 let g:GPGPreferSymmetric = 0 | |
196 endif | |
197 | |
198 " check if armored files are preferred | |
199 if (!exists("g:GPGPreferArmor")) | |
200 let g:GPGPreferArmor = 0 | |
201 endif | |
202 | |
203 " check if signed files are preferred | |
204 if (!exists("g:GPGPreferSign")) | |
205 let g:GPGPreferSign = 0 | |
206 endif | |
207 | |
208 " start with empty default recipients if none is defined so far | |
209 if (!exists("g:GPGDefaultRecipients")) | |
210 let g:GPGDefaultRecipients = [] | |
211 endif | |
212 | |
213 " print version | |
214 call s:GPGDebug(1, "gnupg.vim ". g:loaded_gnupg) | |
215 | |
216 " determine if gnupg can use the gpg-agent | |
217 if (exists("$GPG_AGENT_INFO") && g:GPGUseAgent == 1) | |
218 if (!exists("$GPG_TTY") && !has("gui_running")) | |
219 let $GPG_TTY = system("tty") | |
220 if (v:shell_error) | |
221 let $GPG_TTY = "" | |
222 echohl GPGError | |
223 echom "The GPG_TTY is not set and no TTY could be found using the `tty` command!" | |
224 echom "gpg-agent might not work." | |
225 echohl None | |
226 endif | |
227 endif | |
228 let s:GPGCommand = g:GPGExecutable . " --use-agent" | |
229 else | |
230 let s:GPGCommand = g:GPGExecutable . " --no-use-agent" | |
231 endif | |
232 | |
233 " don't use tty in gvim | |
234 " FIXME find a better way to avoid an error. | |
235 " with this solution only --use-agent will work | |
236 if (has("gui_running")) | |
237 let s:GPGCommand = s:GPGCommand . " --no-tty" | |
238 endif | |
239 | |
240 " setup shell environment for unix and windows | |
241 let s:shellredirsave = &shellredir | |
242 let s:shellsave = &shell | |
243 if (has("unix")) | |
244 " unix specific settings | |
245 let s:shellredir = ">%s 2>&1" | |
246 let s:shell = '/bin/sh' | |
247 let s:stderrredirnull = '2>/dev/null' | |
248 let s:GPGCommand = "LANG=C LC_ALL=C " . s:GPGCommand | |
249 else | |
250 " windows specific settings | |
251 let s:shellredir = '>%s' | |
252 let s:shell = &shell | |
253 let s:stderrredirnull = '2>nul' | |
254 endif | |
255 | |
256 call s:GPGDebug(3, "shellredirsave: " . s:shellredirsave) | |
257 call s:GPGDebug(3, "shellsave: " . s:shellsave) | |
258 | |
259 call s:GPGDebug(3, "shell: " . s:shell) | |
260 call s:GPGDebug(3, "shellcmdflag: " . &shellcmdflag) | |
261 call s:GPGDebug(3, "shellxquote: " . &shellxquote) | |
262 call s:GPGDebug(3, "shellredir: " . s:shellredir) | |
263 call s:GPGDebug(3, "stderrredirnull: " . s:stderrredirnull) | |
264 | |
265 call s:GPGDebug(3, "shell implementation: " . resolve(s:shell)) | |
266 | |
267 " find the supported algorithms | |
268 let commandline = s:GPGCommand . " --version" | |
269 call s:GPGDebug(2, "command: ". commandline) | |
270 let &shellredir = s:shellredir | |
271 let &shell = s:shell | |
272 let output = system(commandline) | |
273 let &shellredir = s:shellredirsave | |
274 let &shell = s:shellsave | |
275 call s:GPGDebug(2, "output: ". output) | |
276 | |
277 let s:GPGPubkey = substitute(output, ".*Pubkey: \\(.\\{-}\\)\n.*", "\\1", "") | |
278 let s:GPGCipher = substitute(output, ".*Cipher: \\(.\\{-}\\)\n.*", "\\1", "") | |
279 let s:GPGHash = substitute(output, ".*Hash: \\(.\\{-}\\)\n.*", "\\1", "") | |
280 let s:GPGCompress = substitute(output, ".*Compress.\\{-}: \\(.\\{-}\\)\n.*", "\\1", "") | |
281 | |
282 call s:GPGDebug(2, "public key algorithms: " . s:GPGPubkey) | |
283 call s:GPGDebug(2, "cipher algorithms: " . s:GPGCipher) | |
284 call s:GPGDebug(2, "hashing algorithms: " . s:GPGHash) | |
285 call s:GPGDebug(2, "compression algorithms: " . s:GPGCompress) | |
286 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGInit()") | |
287 endfunction | |
288 | |
289 " Function: s:GPGCleanup() {{{2 | |
290 " | |
291 " cleanup on leaving vim | |
292 " | |
293 function s:GPGCleanup() | |
294 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGCleanup()") | |
295 | |
296 " wipe out screen | |
297 new +only | |
298 redraw! | |
299 | |
300 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGCleanup()") | |
301 endfunction | |
302 | |
303 " Function: s:GPGDecrypt() {{{2 | |
304 " | |
305 " decrypt the buffer and find all recipients of the encrypted file | |
306 " | |
307 function s:GPGDecrypt() | |
308 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGDecrypt()") | |
309 | |
310 " switch to binary mode to read the encrypted file | |
311 set bin | |
312 | |
313 " get the filename of the current buffer | |
314 let filename = escape(expand("%:p"), '\"') | |
315 | |
316 " clear GPGEncrypted, GPGRecipients and GPGOptions | |
317 let b:GPGEncrypted = 0 | |
318 let b:GPGRecipients = [] | |
319 let b:GPGOptions = [] | |
320 | |
321 " find the recipients of the file | |
322 let commandline = s:GPGCommand . " --verbose --decrypt --list-only --dry-run --batch --no-use-agent --logger-fd 1 \"" . filename . "\"" | |
323 call s:GPGDebug(3, "command: " . commandline) | |
324 let &shellredir = s:shellredir | |
325 let &shell = s:shell | |
326 let output = system(commandline) | |
327 let &shellredir = s:shellredirsave | |
328 let &shell = s:shellsave | |
329 call s:GPGDebug(3, "output: ". output) | |
330 | |
331 " check if the file is symmetric/asymmetric encrypted | |
332 if (match(output, "gpg: encrypted with [[:digit:]]\\+ passphrase") >= 0) | |
333 " file is symmetric encrypted | |
334 let b:GPGEncrypted = 1 | |
335 call s:GPGDebug(1, "this file is symmetric encrypted") | |
336 | |
337 let b:GPGOptions += ["symmetric"] | |
338 | |
339 " find the used cipher algorithm | |
340 let cipher = substitute(output, ".*gpg: \\([^ ]\\+\\) encrypted data.*", "\\1", "") | |
341 if (match(s:GPGCipher, "\\<" . cipher . "\\>") >= 0) | |
342 let b:GPGOptions += ["cipher-algo " . cipher] | |
343 call s:GPGDebug(1, "cipher-algo is " . cipher) | |
344 else | |
345 echohl GPGWarning | |
346 echom "The cipher " . cipher . " is not known by the local gpg command. Using default!" | |
347 echo | |
348 echohl None | |
349 endif | |
350 elseif (match(output, "gpg: public key is [[:xdigit:]]\\{8}") >= 0) | |
351 " file is asymmetric encrypted | |
352 let b:GPGEncrypted = 1 | |
353 call s:GPGDebug(1, "this file is asymmetric encrypted") | |
354 | |
355 let b:GPGOptions += ["encrypt"] | |
356 | |
357 " find the used public keys | |
358 let start = match(output, "gpg: public key is [[:xdigit:]]\\{8}") | |
359 while (start >= 0) | |
360 let start = start + strlen("gpg: public key is ") | |
361 let recipient = strpart(output, start, 8) | |
362 call s:GPGDebug(1, "recipient is " . recipient) | |
363 let name = s:GPGNameToID(recipient) | |
364 if (strlen(name) > 0) | |
365 let b:GPGRecipients += [name] | |
366 call s:GPGDebug(1, "name of recipient is " . name) | |
367 else | |
368 let b:GPGRecipients += [recipient] | |
369 echohl GPGWarning | |
370 echom "The recipient \"" . recipient . "\" is not in your public keyring!" | |
371 echohl None | |
372 end | |
373 let start = match(output, "gpg: public key is [[:xdigit:]]\\{8}", start) | |
374 endwhile | |
375 else | |
376 " file is not encrypted | |
377 let b:GPGEncrypted = 0 | |
378 call s:GPGDebug(1, "this file is not encrypted") | |
379 echohl GPGWarning | |
380 echom "File is not encrypted, all GPG functions disabled!" | |
381 echohl None | |
382 set nobin | |
383 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()") | |
384 return | |
385 endif | |
386 | |
387 " check if the message is armored | |
388 if (match(output, "gpg: armor header") >= 0) | |
389 call s:GPGDebug(1, "this file is armored") | |
390 let b:GPGOptions += ["armor"] | |
391 endif | |
392 | |
393 " finally decrypt the buffer content | |
394 " since even with the --quiet option passphrase typos will be reported, | |
395 " we must redirect stderr (using shell temporarily) | |
396 call s:GPGDebug(1, "decrypting file") | |
397 let commandline = "'[,']!" . s:GPGCommand . " --quiet --decrypt " . s:stderrredirnull | |
398 call s:GPGDebug(1, "command: " . commandline) | |
399 let &shellredir = s:shellredir | |
400 let &shell = s:shell | |
401 execute commandline | |
402 let &shellredir = s:shellredirsave | |
403 let &shell = s:shellsave | |
404 if (v:shell_error) " message could not be decrypted | |
405 silent u | |
406 echohl GPGError | |
407 let blackhole = input("Message could not be decrypted! (Press ENTER)") | |
408 echohl None | |
409 bwipeout | |
410 set nobin | |
411 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()") | |
412 return | |
413 endif | |
414 | |
415 " turn off binary mode | |
416 set nobin | |
417 | |
418 " call the autocommand for the file minus .gpg$ | |
419 execute ":doautocmd BufReadPost " . escape(expand("%:r"), ' *?\"'."'") | |
420 call s:GPGDebug(2, "called autocommand for " . escape(expand("%:r"), ' *?\"'."'")) | |
421 | |
422 " refresh screen | |
423 redraw! | |
424 | |
425 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()") | |
426 endfunction | |
427 | |
428 " Function: s:GPGEncrypt() {{{2 | |
429 " | |
430 " encrypts the buffer to all previous recipients | |
431 " | |
432 function s:GPGEncrypt() | |
433 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEncrypt()") | |
434 | |
435 " save window view | |
436 let s:GPGWindowView = winsaveview() | |
437 call s:GPGDebug(2, "saved window view " . string(s:GPGWindowView)) | |
438 | |
439 " store encoding and switch to a safe one | |
440 if (&fileencoding != &encoding) | |
441 let s:GPGEncoding = &encoding | |
442 let &encoding = &fileencoding | |
443 call s:GPGDebug(2, "encoding was \"" . s:GPGEncoding . "\", switched to \"" . &encoding . "\"") | |
444 else | |
445 let s:GPGEncoding = "" | |
446 call s:GPGDebug(2, "encoding and fileencoding are the same (\"" . &encoding . "\"), not switching") | |
447 endif | |
448 | |
449 " switch buffer to binary mode | |
450 set bin | |
451 | |
452 " guard for unencrypted files | |
453 if (!exists("b:GPGEncrypted") || b:GPGEncrypted == 0) | |
454 echohl GPGError | |
455 let blackhole = input("Message could not be encrypted! File might be empty! (Press ENTER)") | |
456 echohl None | |
457 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()") | |
458 return | |
459 endif | |
460 | |
461 " initialize GPGOptions if not happened before | |
462 if (!exists("b:GPGOptions") || len(b:GPGOptions) == 0) | |
463 let b:GPGOptions = [] | |
464 if (exists("g:GPGPreferSymmetric") && g:GPGPreferSymmetric == 1) | |
465 let b:GPGOptions += ["symmetric"] | |
466 let b:GPGRecipients = [] | |
467 else | |
468 let b:GPGOptions += ["encrypt"] | |
469 endif | |
470 if (exists("g:GPGPreferArmor") && g:GPGPreferArmor == 1) | |
471 let b:GPGOptions += ["armor"] | |
472 endif | |
473 if (exists("g:GPGPreferSign") && g:GPGPreferSign == 1) | |
474 let b:GPGOptions += ["sign"] | |
475 endif | |
476 call s:GPGDebug(1, "no options set, so using default options: " . string(b:GPGOptions)) | |
477 endif | |
478 | |
479 " built list of options | |
480 let options = "" | |
481 for option in b:GPGOptions | |
482 let options = options . " --" . option . " " | |
483 endfor | |
484 | |
485 " check here again if all recipients are available in the keyring | |
486 let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients) | |
487 | |
488 " check if there are unknown recipients and warn | |
489 if (len(unknownrecipients) > 0) | |
490 echohl GPGWarning | |
491 echom "Please use GPGEditRecipients to correct!!" | |
492 echo | |
493 echohl None | |
494 | |
495 " Let user know whats happend and copy known_recipients back to buffer | |
496 let dummy = input("Press ENTER to quit") | |
497 endif | |
498 | |
499 " built list of recipients | |
500 if (len(recipients) > 0) | |
501 for gpgid in recipients | |
502 let options = options . " -r " . gpgid | |
503 endfor | |
504 else | |
505 if (match(b:GPGOptions, "encrypt") >= 0) | |
506 echohl GPGError | |
507 echom "There are no recipients!!" | |
508 echom "Please use GPGEditRecipients to correct!!" | |
509 echo | |
510 echohl None | |
511 endif | |
512 endif | |
513 | |
514 " encrypt the buffer | |
515 let commandline = "'[,']!" . s:GPGCommand . " --quiet --no-encrypt-to " . options . " " . s:stderrredirnull | |
516 call s:GPGDebug(1, "command: " . commandline) | |
517 let &shellredir = s:shellredir | |
518 let &shell = s:shell | |
519 silent execute commandline | |
520 let &shellredir = s:shellredirsave | |
521 let &shell = s:shellsave | |
522 if (v:shell_error) " message could not be encrypted | |
523 " delete content of the buffer to be sure no data is written unencrypted | |
524 " content will be recovered in GPGEncryptPost() | |
525 silent normal! 1GdG | |
526 | |
527 echohl GPGError | |
528 let blackhole = input("Message could not be encrypted! File might be empty! (Press ENTER)") | |
529 echohl None | |
530 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()") | |
531 return | |
532 endif | |
533 | |
534 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()") | |
535 endfunction | |
536 | |
537 " Function: s:GPGEncryptPost() {{{2 | |
538 " | |
539 " undo changes don by encrypt, after writing | |
540 " | |
541 function s:GPGEncryptPost() | |
542 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEncryptPost()") | |
543 | |
544 " guard for unencrypted files | |
545 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
546 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncryptPost()") | |
547 return | |
548 endif | |
549 | |
550 " undo encryption of buffer content | |
551 silent u | |
552 | |
553 " switch back from binary mode | |
554 set nobin | |
555 | |
556 " restore encoding | |
557 if (s:GPGEncoding != "") | |
558 let &encoding = s:GPGEncoding | |
559 call s:GPGDebug(2, "restored encoding \"" . &encoding . "\"") | |
560 endif | |
561 | |
562 " restore window view | |
563 call winrestview(s:GPGWindowView) | |
564 call s:GPGDebug(2, "restored window view" . string(s:GPGWindowView)) | |
565 | |
566 " refresh screen | |
567 redraw! | |
568 | |
569 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncryptPost()") | |
570 endfunction | |
571 | |
572 " Function: s:GPGViewRecipients() {{{2 | |
573 " | |
574 " echo the recipients | |
575 " | |
576 function s:GPGViewRecipients() | |
577 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGViewRecipients()") | |
578 | |
579 " guard for unencrypted files | |
580 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
581 echohl GPGWarning | |
582 echom "File is not encrypted, all GPG functions disabled!" | |
583 echohl None | |
584 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewRecipients()") | |
585 return | |
586 endif | |
587 | |
588 let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients) | |
589 | |
590 echo 'This file has following recipients (Unknown recipients have a prepended "!"):' | |
591 " echo the recipients | |
592 for name in recipients | |
593 let name = s:GPGIDToName(name) | |
594 echo name | |
595 endfor | |
596 | |
597 " echo the unknown recipients | |
598 echohl GPGWarning | |
599 for name in unknownrecipients | |
600 let name = "!" . name | |
601 echo name | |
602 endfor | |
603 echohl None | |
604 | |
605 " check if there is any known recipient | |
606 if (len(recipients) == 0) | |
607 echohl GPGError | |
608 echom 'There are no known recipients!' | |
609 echohl None | |
610 endif | |
611 | |
612 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewRecipients()") | |
613 endfunction | |
614 | |
615 " Function: s:GPGEditRecipients() {{{2 | |
616 " | |
617 " create a scratch buffer with all recipients to add/remove recipients | |
618 " | |
619 function s:GPGEditRecipients() | |
620 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEditRecipients()") | |
621 | |
622 " guard for unencrypted files | |
623 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
624 echohl GPGWarning | |
625 echom "File is not encrypted, all GPG functions disabled!" | |
626 echohl None | |
627 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditRecipients()") | |
628 return | |
629 endif | |
630 | |
631 " only do this if it isn't already a GPGRecipients_* buffer | |
632 if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0) | |
633 | |
634 " save buffer name | |
635 let buffername = bufname("%") | |
636 let editbuffername = "GPGRecipients_" . buffername | |
637 | |
638 " check if this buffer exists | |
639 if (!bufexists(editbuffername)) | |
640 " create scratch buffer | |
641 execute 'silent! split ' . escape(editbuffername, ' *?\"'."'") | |
642 | |
643 " add a autocommand to regenerate the recipients after a write | |
644 autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishRecipientsBuffer() | |
645 else | |
646 if (bufwinnr(editbuffername) >= 0) | |
647 " switch to scratch buffer window | |
648 execute 'silent! ' . bufwinnr(editbuffername) . "wincmd w" | |
649 else | |
650 " split scratch buffer window | |
651 execute 'silent! sbuffer ' . escape(editbuffername, ' *?\"'."'") | |
652 | |
653 " add a autocommand to regenerate the recipients after a write | |
654 autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishRecipientsBuffer() | |
655 endif | |
656 | |
657 " empty the buffer | |
658 silent normal! 1GdG | |
659 endif | |
660 | |
661 " Mark the buffer as a scratch buffer | |
662 setlocal buftype=acwrite | |
663 setlocal bufhidden=hide | |
664 setlocal noswapfile | |
665 setlocal nowrap | |
666 setlocal nobuflisted | |
667 setlocal nonumber | |
668 | |
669 " so we know for which other buffer this edit buffer is | |
670 let b:GPGCorrespondingTo = buffername | |
671 | |
672 " put some comments to the scratch buffer | |
673 silent put ='GPG: ----------------------------------------------------------------------' | |
674 silent put ='GPG: Please edit the list of recipients, one recipient per line.' | |
675 silent put ='GPG: Unknown recipients have a prepended \"!\".' | |
676 silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically.' | |
677 silent put ='GPG: Data after recipients between and including \"(\" and \")\" is ignored.' | |
678 silent put ='GPG: Closing this buffer commits changes.' | |
679 silent put ='GPG: ----------------------------------------------------------------------' | |
680 | |
681 " get the recipients | |
682 let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(getbufvar(b:GPGCorrespondingTo, "GPGRecipients")) | |
683 | |
684 " if there are no known or unknown recipients, use the default ones | |
685 if (len(recipients) == 0 && len(unknownrecipients) == 0) | |
686 if (type(g:GPGDefaultRecipients) == type([])) | |
687 let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(g:GPGDefaultRecipients) | |
688 else | |
689 echohl GPGWarning | |
690 echom "g:GPGDefaultRecipients is not a Vim list, please correct this in your vimrc!" | |
691 echohl None | |
692 endif | |
693 endif | |
694 | |
695 " put the recipients in the scratch buffer | |
696 for name in recipients | |
697 let name = s:GPGIDToName(name) | |
698 silent put =name | |
699 endfor | |
700 | |
701 " put the unknown recipients in the scratch buffer | |
702 let syntaxPattern = "\\(nonexxistinwordinthisbuffer" | |
703 for name in unknownrecipients | |
704 let name = "!" . name | |
705 let syntaxPattern = syntaxPattern . "\\|" . name | |
706 silent put =name | |
707 endfor | |
708 let syntaxPattern = syntaxPattern . "\\)" | |
709 | |
710 " define highlight | |
711 if (has("syntax") && exists("g:syntax_on")) | |
712 execute 'syntax match GPGUnknownRecipient "' . syntaxPattern . '"' | |
713 highlight clear GPGUnknownRecipient | |
714 highlight link GPGUnknownRecipient GPGHighlightUnknownRecipient | |
715 | |
716 syntax match GPGComment "^GPG:.*$" | |
717 execute 'syntax match GPGComment "' . s:GPGMagicString . '.*$"' | |
718 highlight clear GPGComment | |
719 highlight link GPGComment Comment | |
720 endif | |
721 | |
722 " delete the empty first line | |
723 silent normal! 1Gdd | |
724 | |
725 " jump to the first recipient | |
726 silent normal! G | |
727 | |
728 endif | |
729 | |
730 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditRecipients()") | |
731 endfunction | |
732 | |
733 " Function: s:GPGFinishRecipientsBuffer() {{{2 | |
734 " | |
735 " create a new recipient list from RecipientsBuffer | |
736 " | |
737 function s:GPGFinishRecipientsBuffer() | |
738 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGFinishRecipientsBuffer()") | |
739 | |
740 " guard for unencrypted files | |
741 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
742 echohl GPGWarning | |
743 echom "File is not encrypted, all GPG functions disabled!" | |
744 echohl None | |
745 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishRecipientsBuffer()") | |
746 return | |
747 endif | |
748 | |
749 " go to buffer before doing work | |
750 if (bufnr("%") != expand("<abuf>")) | |
751 " switch to scratch buffer window | |
752 execute 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w" | |
753 endif | |
754 | |
755 " delete the autocommand | |
756 autocmd! * <buffer> | |
757 | |
758 | |
759 " get the recipients from the scratch buffer | |
760 let recipients = [] | |
761 let lines = getline(1,"$") | |
762 for recipient in lines | |
763 " delete all text after magic string | |
764 let recipient = substitute(recipient, s:GPGMagicString . ".*$", "", "") | |
765 | |
766 " delete all spaces at beginning and end of the recipient | |
767 " also delete a '!' at the beginning of the recipient | |
768 let recipient = substitute(recipient, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "") | |
769 | |
770 " delete comment lines | |
771 let recipient = substitute(recipient, "^GPG:.*$", "", "") | |
772 | |
773 " only do this if the line is not empty | |
774 if (strlen(recipient) > 0) | |
775 let gpgid = s:GPGNameToID(recipient) | |
776 if (strlen(gpgid) > 0) | |
777 if (match(recipients, gpgid) < 0) | |
778 let recipients += [gpgid] | |
779 endif | |
780 else | |
781 if (match(recipients, recipient) < 0) | |
782 let recipients += [recipient] | |
783 echohl GPGWarning | |
784 echom "The recipient \"" . recipient . "\" is not in your public keyring!" | |
785 echohl None | |
786 endif | |
787 endif | |
788 endif | |
789 endfor | |
790 | |
791 " write back the new recipient list to the corresponding buffer and mark it | |
792 " as modified. Buffer is now for sure a encrypted buffer. | |
793 call setbufvar(b:GPGCorrespondingTo, "GPGRecipients", recipients) | |
794 call setbufvar(b:GPGCorrespondingTo, "&mod", 1) | |
795 call setbufvar(b:GPGCorrespondingTo, "GPGEncrypted", 1) | |
796 | |
797 " check if there is any known recipient | |
798 if (len(recipients) == 0) | |
799 echohl GPGError | |
800 echom 'There are no known recipients!' | |
801 echohl None | |
802 endif | |
803 | |
804 " reset modified flag | |
805 set nomodified | |
806 | |
807 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishRecipientsBuffer()") | |
808 endfunction | |
809 | |
810 " Function: s:GPGViewOptions() {{{2 | |
811 " | |
812 " echo the recipients | |
813 " | |
814 function s:GPGViewOptions() | |
815 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGViewOptions()") | |
816 | |
817 " guard for unencrypted files | |
818 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
819 echohl GPGWarning | |
820 echom "File is not encrypted, all GPG functions disabled!" | |
821 echohl None | |
822 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewOptions()") | |
823 return | |
824 endif | |
825 | |
826 if (exists("b:GPGOptions")) | |
827 echo 'This file has following options:' | |
828 " echo the options | |
829 for option in b:GPGOptions | |
830 echo option | |
831 endfor | |
832 endif | |
833 | |
834 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewOptions()") | |
835 endfunction | |
836 | |
837 " Function: s:GPGEditOptions() {{{2 | |
838 " | |
839 " create a scratch buffer with all recipients to add/remove recipients | |
840 " | |
841 function s:GPGEditOptions() | |
842 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEditOptions()") | |
843 | |
844 " guard for unencrypted files | |
845 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
846 echohl GPGWarning | |
847 echom "File is not encrypted, all GPG functions disabled!" | |
848 echohl None | |
849 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditOptions()") | |
850 return | |
851 endif | |
852 | |
853 " only do this if it isn't already a GPGOptions_* buffer | |
854 if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0) | |
855 | |
856 " save buffer name | |
857 let buffername = bufname("%") | |
858 let editbuffername = "GPGOptions_" . buffername | |
859 | |
860 " check if this buffer exists | |
861 if (!bufexists(editbuffername)) | |
862 " create scratch buffer | |
863 execute 'silent! split ' . escape(editbuffername, ' *?\"'."'") | |
864 | |
865 " add a autocommand to regenerate the options after a write | |
866 autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishOptionsBuffer() | |
867 else | |
868 if (bufwinnr(editbuffername) >= 0) | |
869 " switch to scratch buffer window | |
870 execute 'silent! ' . bufwinnr(editbuffername) . "wincmd w" | |
871 else | |
872 " split scratch buffer window | |
873 execute 'silent! sbuffer ' . escape(editbuffername, ' *?\"'."'") | |
874 | |
875 " add a autocommand to regenerate the options after a write | |
876 autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishOptionsBuffer() | |
877 endif | |
878 | |
879 " empty the buffer | |
880 silent normal! 1GdG | |
881 endif | |
882 | |
883 " Mark the buffer as a scratch buffer | |
884 setlocal buftype=nofile | |
885 setlocal noswapfile | |
886 setlocal nowrap | |
887 setlocal nobuflisted | |
888 setlocal nonumber | |
889 | |
890 " so we know for which other buffer this edit buffer is | |
891 let b:GPGCorrespondingTo = buffername | |
892 | |
893 " put some comments to the scratch buffer | |
894 silent put ='GPG: ----------------------------------------------------------------------' | |
895 silent put ='GPG: THERE IS NO CHECK OF THE ENTERED OPTIONS!' | |
896 silent put ='GPG: YOU NEED TO KNOW WHAT YOU ARE DOING!' | |
897 silent put ='GPG: IF IN DOUBT, QUICKLY EXIT USING :x OR :bd.' | |
898 silent put ='GPG: Please edit the list of options, one option per line.' | |
899 silent put ='GPG: Please refer to the gpg documentation for valid options.' | |
900 silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically.' | |
901 silent put ='GPG: Closing this buffer commits changes.' | |
902 silent put ='GPG: ----------------------------------------------------------------------' | |
903 | |
904 " put the options in the scratch buffer | |
905 let options = getbufvar(b:GPGCorrespondingTo, "GPGOptions") | |
906 | |
907 for option in options | |
908 silent put =option | |
909 endfor | |
910 | |
911 " delete the empty first line | |
912 silent normal! 1Gdd | |
913 | |
914 " jump to the first option | |
915 silent normal! G | |
916 | |
917 " define highlight | |
918 if (has("syntax") && exists("g:syntax_on")) | |
919 syntax match GPGComment "^GPG:.*$" | |
920 highlight clear GPGComment | |
921 highlight link GPGComment Comment | |
922 endif | |
923 endif | |
924 | |
925 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditOptions()") | |
926 endfunction | |
927 | |
928 " Function: s:GPGFinishOptionsBuffer() {{{2 | |
929 " | |
930 " create a new option list from OptionsBuffer | |
931 " | |
932 function s:GPGFinishOptionsBuffer() | |
933 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGFinishOptionsBuffer()") | |
934 | |
935 " guard for unencrypted files | |
936 if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) | |
937 echohl GPGWarning | |
938 echom "File is not encrypted, all GPG functions disabled!" | |
939 echohl None | |
940 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishOptionsBuffer()") | |
941 return | |
942 endif | |
943 | |
944 " go to buffer before doing work | |
945 if (bufnr("%") != expand("<abuf>")) | |
946 " switch to scratch buffer window | |
947 execute 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w" | |
948 endif | |
949 | |
950 " clear options and unknownOptions | |
951 let options = [] | |
952 let unknownOptions = [] | |
953 | |
954 " delete the autocommand | |
955 autocmd! * <buffer> | |
956 | |
957 " get the options from the scratch buffer | |
958 let lines = getline(1, "$") | |
959 for option in lines | |
960 " delete all spaces at beginning and end of the option | |
961 " also delete a '!' at the beginning of the option | |
962 let option = substitute(option, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "") | |
963 " delete comment lines | |
964 let option = substitute(option, "^GPG:.*$", "", "") | |
965 | |
966 " only do this if the line is not empty | |
967 if (strlen(option) > 0 && match(options, option) < 0) | |
968 let options += [option] | |
969 endif | |
970 endfor | |
971 | |
972 " write back the new option list to the corresponding buffer and mark it | |
973 " as modified | |
974 call setbufvar(b:GPGCorrespondingTo, "GPGOptions", options) | |
975 call setbufvar(b:GPGCorrespondingTo, "&mod", 1) | |
976 | |
977 " reset modified flag | |
978 set nomodified | |
979 | |
980 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishOptionsBuffer()") | |
981 endfunction | |
982 | |
983 " Function: s:GPGCheckRecipients(tocheck) {{{2 | |
984 " | |
985 " check if recipients are known | |
986 " Returns: two lists recipients and unknownrecipients | |
987 " | |
988 function s:GPGCheckRecipients(tocheck) | |
989 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGCheckRecipients()") | |
990 | |
991 let recipients = [] | |
992 let unknownrecipients = [] | |
993 | |
994 if (type(a:tocheck) == type([])) | |
995 for recipient in a:tocheck | |
996 let gpgid = s:GPGNameToID(recipient) | |
997 if (strlen(gpgid) > 0) | |
998 if (match(recipients, gpgid) < 0) | |
999 let recipients += [gpgid] | |
1000 endif | |
1001 else | |
1002 if (match(unknownrecipients, recipient) < 0) | |
1003 let unknownrecipients += [recipient] | |
1004 echohl GPGWarning | |
1005 echom "The recipient \"" . recipient . "\" is not in your public keyring!" | |
1006 echohl None | |
1007 endif | |
1008 end | |
1009 endfor | |
1010 endif | |
1011 | |
1012 call s:GPGDebug(2, "recipients are: " . string(recipients)) | |
1013 call s:GPGDebug(2, "unknown recipients are: " . string(unknownrecipients)) | |
1014 | |
1015 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGCheckRecipients()") | |
1016 return [ recipients, unknownrecipients ] | |
1017 endfunction | |
1018 | |
1019 " Function: s:GPGNameToID(name) {{{2 | |
1020 " | |
1021 " find GPG key ID corresponding to a name | |
1022 " Returns: ID for the given name | |
1023 " | |
1024 function s:GPGNameToID(name) | |
1025 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGNameToID()") | |
1026 | |
1027 " ask gpg for the id for a name | |
1028 let commandline = s:GPGCommand . " --quiet --with-colons --fixed-list-mode --list-keys \"" . a:name . "\"" | |
1029 call s:GPGDebug(2, "command: ". commandline) | |
1030 let &shellredir = s:shellredir | |
1031 let &shell = s:shell | |
1032 let output = system(commandline) | |
1033 let &shellredir = s:shellredirsave | |
1034 let &shell = s:shellsave | |
1035 call s:GPGDebug(2, "output: ". output) | |
1036 | |
1037 " when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8, | |
1038 " so convert it, if necessary | |
1039 if (&encoding != "utf-8") | |
1040 let output = iconv(output, "utf-8", &encoding) | |
1041 endif | |
1042 let lines = split(output, "\n") | |
1043 | |
1044 " parse the output of gpg | |
1045 let pubseen = 0 | |
1046 let counter = 0 | |
1047 let gpgids = [] | |
1048 let choices = "The name \"" . a:name . "\" is ambiguous. Please select the correct key:\n" | |
1049 for line in lines | |
1050 let fields = split(line, ":") | |
1051 " search for the next uid | |
1052 if (pubseen == 1) | |
1053 if (fields[0] == "uid") | |
1054 let choices = choices . " " . fields[9] . "\n" | |
1055 else | |
1056 let pubseen = 0 | |
1057 endif | |
1058 endif | |
1059 | |
1060 " search for the next pub | |
1061 if (pubseen == 0) | |
1062 if (fields[0] == "pub") | |
1063 let identity = fields[4] | |
1064 let gpgids += [identity] | |
1065 if exists("*strftime") | |
1066 let choices = choices . counter . ": ID: 0x" . identity . " created at " . strftime("%c", fields[5]) . "\n" | |
1067 else | |
1068 let choices = choices . counter . ": ID: 0x" . identity . "\n" | |
1069 endif | |
1070 let counter = counter+1 | |
1071 let pubseen = 1 | |
1072 endif | |
1073 endif | |
1074 | |
1075 endfor | |
1076 | |
1077 " counter > 1 means we have more than one results | |
1078 let answer = 0 | |
1079 if (counter > 1) | |
1080 let choices = choices . "Enter number: " | |
1081 let answer = input(choices, "0") | |
1082 while (answer == "") | |
1083 let answer = input("Enter number: ", "0") | |
1084 endwhile | |
1085 endif | |
1086 | |
1087 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGIDToName()") | |
1088 return get(gpgids, answer, "") | |
1089 endfunction | |
1090 | |
1091 " Function: s:GPGIDToName(identity) {{{2 | |
1092 " | |
1093 " find name corresponding to a GPG key ID | |
1094 " Returns: Name for the given ID | |
1095 " | |
1096 function s:GPGIDToName(identity) | |
1097 call s:GPGDebug(3, ">>>>>>>> Entering s:GPGIDToName()") | |
1098 | |
1099 " TODO is the encryption subkey really unique? | |
1100 | |
1101 " ask gpg for the id for a name | |
1102 let commandline = s:GPGCommand . " --quiet --with-colons --fixed-list-mode --list-keys " . a:identity | |
1103 call s:GPGDebug(2, "command: ". commandline) | |
1104 let &shellredir = s:shellredir | |
1105 let &shell = s:shell | |
1106 let output = system(commandline) | |
1107 let &shellredir = s:shellredirsave | |
1108 let &shell = s:shellsave | |
1109 call s:GPGDebug(2, "output: ". output) | |
1110 | |
1111 " when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8, | |
1112 " so convert it, if necessary | |
1113 if (&encoding != "utf-8") | |
1114 let output = iconv(output, "utf-8", &encoding) | |
1115 endif | |
1116 let lines = split(output, "\n") | |
1117 | |
1118 " parse the output of gpg | |
1119 let pubseen = 0 | |
1120 let uid = "" | |
1121 for line in lines | |
1122 let fields = split(line, ":") | |
1123 if (pubseen == 0) " search for the next pub | |
1124 if (fields[0] == "pub") | |
1125 let pubseen = 1 | |
1126 endif | |
1127 else " search for the next uid | |
1128 if (fields[0] == "uid") | |
1129 let pubseen = 0 | |
1130 if exists("*strftime") | |
1131 let uid = fields[9] . s:GPGMagicString . "(ID: 0x" . a:identity . " created at " . strftime("%c", fields[5]) . ")" | |
1132 else | |
1133 let uid = fields[9] . s:GPGMagicString . "(ID: 0x" . a:identity . ")" | |
1134 endif | |
1135 break | |
1136 endif | |
1137 endif | |
1138 endfor | |
1139 | |
1140 call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGIDToName()") | |
1141 return uid | |
1142 endfunction | |
1143 | |
1144 " Function: s:GPGDebug(level, text) {{{2 | |
1145 " | |
1146 " output debug message, if this message has high enough importance | |
1147 " only define function if GPGDebugLevel set at all | |
1148 " | |
1149 function s:GPGDebug(level, text) | |
1150 if exists("g:GPGDebugLevel") && g:GPGDebugLevel >= a:level | |
1151 if exists("g:GPGDebugLog") | |
1152 execute "redir >> " . g:GPGDebugLog | |
1153 echom "GnuPG: " . a:text | |
1154 redir END | |
1155 else | |
1156 echom "GnuPG: " . a:text | |
1157 endif | |
1158 endif | |
1159 endfunction | |
1160 | |
1161 " Section: Commands {{{1 | |
1162 | |
1163 command! GPGViewRecipients call s:GPGViewRecipients() | |
1164 command! GPGEditRecipients call s:GPGEditRecipients() | |
1165 command! GPGViewOptions call s:GPGViewOptions() | |
1166 command! GPGEditOptions call s:GPGEditOptions() | |
1167 | |
1168 " Section: Menu {{{1 | |
1169 | |
1170 if (has("menu")) | |
1171 amenu <silent> Plugin.GnuPG.View\ Recipients :GPGViewRecipients<CR> | |
1172 amenu <silent> Plugin.GnuPG.Edit\ Recipients :GPGEditRecipients<CR> | |
1173 amenu <silent> Plugin.GnuPG.View\ Options :GPGViewOptions<CR> | |
1174 amenu <silent> Plugin.GnuPG.Edit\ Options :GPGEditOptions<CR> | |
1175 endif | |
1176 | |
1177 " vim600: set foldmethod=marker foldlevel=0 : |