aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno2012-04-26 11:03:19 +0900
committerDaiki Ueno2012-04-26 11:03:19 +0900
commit823ad1d7e83d2e98ba19d686f3c310707ca27c9a (patch)
tree760fb7be50307daa5e1e042088d89dab0c53dc61
parent8a4ca8e339479442885e7c79af1ec32cb79b7895 (diff)
downloademacs-823ad1d7e83d2e98ba19d686f3c310707ca27c9a.tar.gz
emacs-823ad1d7e83d2e98ba19d686f3c310707ca27c9a.zip
Revive plstore editing mode previously reverted due to feature freeze.
-rw-r--r--lisp/gnus/ChangeLog10
-rw-r--r--lisp/gnus/plstore.el135
2 files changed, 139 insertions, 6 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 52f140d9192..be4d0675781 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,13 @@
12012-04-26 Daiki Ueno <ueno@unixuser.org>
2
3 * plstore.el: Revive the editing feature.
4 (plstore-mode): New mode to edit plstore file.
5 (plstore-mode-toggle-display, plstore-mode-original)
6 (plstore-mode-decoded): New command.
7 (plstore--encode, plstore--decode, plstore--write-contents-functions)
8 (plstore--insert-buffer, plstore--make): New function.
9 (plstore-open, plstore-save): Simplify by using them.
10
12012-04-16 Glenn Morris <rgm@gnu.org> 112012-04-16 Glenn Morris <rgm@gnu.org>
2 12
3 * nndraft.el (nndraft-request-list): Fix declaration. 13 * nndraft.el (nndraft-request-list): Fix declaration.
diff --git a/lisp/gnus/plstore.el b/lisp/gnus/plstore.el
index cbd5e2a3b0a..2f446c84071 100644
--- a/lisp/gnus/plstore.el
+++ b/lisp/gnus/plstore.el
@@ -64,8 +64,18 @@
64;; 64;;
65;; Editing: 65;; Editing:
66;; 66;;
67;; Currently not supported but in the future plstore will provide a 67;; This file also provides `plstore-mode', a major mode for editing
68;; major mode to edit PLSTORE files. 68;; the PLSTORE format file. Visit a non-existing file and put the
69;; following line:
70;;
71;; (("foo" :host "foo.example.org" :secret-user "user"))
72;;
73;; where the prefixing `:secret-' means the property (without
74;; `:secret-' prefix) is marked as secret. Thus, when you save the
75;; buffer, the `:secret-user' property is encrypted as `:user'.
76;;
77;; You can toggle the view between encrypted form and the decrypted
78;; form with C-c C-c.
69 79
70;;; Code: 80;;; Code:
71 81
@@ -107,6 +117,10 @@ symmetric encryption will be used.")
107 117
108(put 'plstore-encrypt-to 'permanent-local t) 118(put 'plstore-encrypt-to 'permanent-local t)
109 119
120(defvar plstore-encoded nil)
121
122(put 'plstore-encoded 'permanent-local t)
123
110(defvar plstore-cache-passphrase-for-symmetric-encryption nil) 124(defvar plstore-cache-passphrase-for-symmetric-encryption nil)
111(defvar plstore-passphrase-alist nil) 125(defvar plstore-passphrase-alist nil)
112 126
@@ -194,10 +208,6 @@ symmetric encryption will be used.")
194 (generate-new-buffer (format " plstore %s" filename)))) 208 (generate-new-buffer (format " plstore %s" filename))))
195 (store (plstore--make buffer))) 209 (store (plstore--make buffer)))
196 (with-current-buffer buffer 210 (with-current-buffer buffer
197 ;; In the future plstore will provide a major mode called
198 ;; `plstore-mode' to edit PLSTORE files.
199 (if (eq major-mode 'plstore-mode)
200 (error "%s is opened for editing; kill the buffer first" file))
201 (erase-buffer) 211 (erase-buffer)
202 (condition-case nil 212 (condition-case nil
203 (insert-file-contents-literally file) 213 (insert-file-contents-literally file)
@@ -435,6 +445,119 @@ If no one is selected, symmetric encryption will be performed. "
435 (plstore--insert-buffer plstore) 445 (plstore--insert-buffer plstore)
436 (save-buffer))) 446 (save-buffer)))
437 447
448(defun plstore--encode (plstore)
449 (plstore--decrypt plstore)
450 (let ((merged-alist (plstore--get-merged-alist plstore)))
451 (concat "("
452 (mapconcat
453 (lambda (entry)
454 (setq entry (copy-sequence entry))
455 (let ((merged-plist (cdr (assoc (car entry) merged-alist)))
456 (plist (cdr entry)))
457 (while plist
458 (if (string-match "\\`:secret-" (symbol-name (car plist)))
459 (setcar (cdr plist)
460 (plist-get
461 merged-plist
462 (intern (concat ":"
463 (substring (symbol-name
464 (car plist))
465 (match-end 0)))))))
466 (setq plist (nthcdr 2 plist)))
467 (prin1-to-string entry)))
468 (plstore--get-alist plstore)
469 "\n")
470 ")")))
471
472(defun plstore--decode (string)
473 (let* ((alist (car (read-from-string string)))
474 (pointer alist)
475 secret-alist
476 plist
477 entry)
478 (while pointer
479 (unless (stringp (car (car pointer)))
480 (error "Invalid PLSTORE format %s" string))
481 (setq plist (cdr (car pointer)))
482 (while plist
483 (when (string-match "\\`:secret-" (symbol-name (car plist)))
484 (setq entry (assoc (car (car pointer)) secret-alist))
485 (unless entry
486 (setq entry (list (car (car pointer)))
487 secret-alist (cons entry secret-alist)))
488 (setcdr entry (plist-put (cdr entry)
489 (intern (concat ":"
490 (substring (symbol-name
491 (car plist))
492 (match-end 0))))
493 (car (cdr plist))))
494 (setcar (cdr plist) t))
495 (setq plist (nthcdr 2 plist)))
496 (setq pointer (cdr pointer)))
497 (plstore--make nil alist nil secret-alist)))
498
499(defun plstore--write-contents-functions ()
500 (when plstore-encoded
501 (let ((store (plstore--decode (buffer-string)))
502 (file (buffer-file-name)))
503 (unwind-protect
504 (progn
505 (set-visited-file-name nil)
506 (with-temp-buffer
507 (plstore--insert-buffer store)
508 (write-region (buffer-string) nil file)))
509 (set-visited-file-name file)
510 (set-buffer-modified-p nil))
511 t)))
512
513(defun plstore-mode-original ()
514 "Show the original form of the this buffer."
515 (interactive)
516 (when plstore-encoded
517 (if (and (buffer-modified-p)
518 (y-or-n-p "Save buffer before reading the original form? "))
519 (save-buffer))
520 (erase-buffer)
521 (insert-file-contents-literally (buffer-file-name))
522 (set-buffer-modified-p nil)
523 (setq plstore-encoded nil)))
524
525(defun plstore-mode-decoded ()
526 "Show the decoded form of the this buffer."
527 (interactive)
528 (unless plstore-encoded
529 (if (and (buffer-modified-p)
530 (y-or-n-p "Save buffer before decoding? "))
531 (save-buffer))
532 (let ((store (plstore--make (current-buffer))))
533 (plstore--init-from-buffer store)
534 (erase-buffer)
535 (insert
536 (substitute-command-keys "\
537;;; You are looking at the decoded form of the PLSTORE file.\n\
538;;; To see the original form content, do \\[plstore-mode-toggle-display]\n\n"))
539 (insert (plstore--encode store))
540 (set-buffer-modified-p nil)
541 (setq plstore-encoded t))))
542
543(defun plstore-mode-toggle-display ()
544 "Toggle the display mode of PLSTORE between the original and decoded forms."
545 (interactive)
546 (if plstore-encoded
547 (plstore-mode-original)
548 (plstore-mode-decoded)))
549
550;;;###autoload
551(define-derived-mode plstore-mode emacs-lisp-mode "PLSTORE"
552 "Major mode for editing PLSTORE files."
553 (make-local-variable 'plstore-encoded)
554 (add-hook 'write-contents-functions #'plstore--write-contents-functions)
555 (define-key plstore-mode-map "\C-c\C-c" #'plstore-mode-toggle-display)
556 ;; to create a new file with plstore-mode, mark it as already decoded
557 (if (called-interactively-p 'any)
558 (setq plstore-encoded t)
559 (plstore-mode-decoded)))
560
438(provide 'plstore) 561(provide 'plstore)
439 562
440;;; plstore.el ends here 563;;; plstore.el ends here