diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2020-05-16 23:53:48 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2020-05-17 00:04:35 +0200 |
commit | d3c15e2b346e89d3d9411137f5b92e51c3679d95 (patch) | |
tree | e3d3e0801678021b40e5f1e178a0a877b2dc29a3 | |
parent | 18d37e580324c5a7b79abe2c10480726fc0e413b (diff) | |
download | org-mode-d3c15e2b346e89d3d9411137f5b92e51c3679d95.tar.gz |
crypt: Small improvements
* lisp/org-crypt.el (org-crypt--encrypted-text): New function.
(org-at-encrypted-entry-p): Better return value and more thorough
checks.
(org-encrypt-entry):
(org-decrypt-entry): Use new function. Better handling of indented
crypted text, and folding.
-rw-r--r-- | lisp/org-crypt.el | 136 |
1 files changed, 80 insertions, 56 deletions
diff --git a/lisp/org-crypt.el b/lisp/org-crypt.el index c5924eb..d458d40 100644 --- a/lisp/org-crypt.el +++ b/lisp/org-crypt.el @@ -124,6 +124,36 @@ nil : Leave auto-save-mode enabled. (const :tag "Ask" ask) (const :tag "Encrypt" encrypt))) +(defun org-crypt--encrypted-text (beg end) + "Return encrypted text in between BEG and END." + ;; Ignore indentation. + (replace-regexp-in-string + "^[ \t]*" "" + (buffer-substring-no-properties beg end))) + +(defun org-at-encrypted-entry-p () + "Is the current entry encrypted? +When the entry is encrypted, return a pair (BEG . END) where BEG +and END are buffer positions delimiting the encrypted area." + (org-with-wide-buffer + (unless (org-before-first-heading-p) + (org-back-to-heading t) + (org-end-of-meta-data) + (let ((case-fold-search nil) + (banner-start (rx (seq bol + (zero-or-more (any "\t ")) + "-----BEGIN PGP MESSAGE-----" + eol)))) + (when (looking-at banner-start) + (let ((start (point)) + (banner-end (rx (seq bol + (or (group (zero-or-more (any "\t ")) + "-----END PGP MESSAGE-----" + eol) + (seq (one-or-more "*") " ")))))) + (when (and (re-search-forward banner-end nil t) (match-string 1)) + (cons start (line-beginning-position 2))))))))) + (defun org-crypt-check-auto-save () "Check whether auto-save-mode is enabled for the current buffer. @@ -166,16 +196,21 @@ Assume `epg-context' is set." (defun org-encrypt-entry () "Encrypt the content of the current headline." (interactive) - (require 'epg) - (org-with-wide-buffer - (org-back-to-heading t) - (let ((start-heading (point))) - (org-end-of-meta-data) - (unless (looking-at-p "-----BEGIN PGP MESSAGE-----") - (setq-local epg-context (epg-make-context nil t t)) - (let ((folded (org-invisible-p)) - (crypt-key (org-crypt-key-for-heading)) - (beg (point))) + (unless (org-at-encrypted-entry-p) + (require 'epg) + (setq-local epg-context (epg-make-context nil t t)) + (org-with-wide-buffer + (org-back-to-heading t) + (let ((start-heading (point)) + (crypt-key (org-crypt-key-for-heading)) + (folded? (org-invisible-p (line-beginning-position)))) + (org-end-of-meta-data) + (let ((beg (point)) + (folded-heading + (and folded? + (save-excursion + (org-previous-visible-heading 1) + (point))))) (goto-char start-heading) (org-end-of-subtree t t) (org-back-over-empty-lines) @@ -195,50 +230,47 @@ Assume `epg-context' is set." (error (insert contents) (error (error-message-string err))))) - (when folded - (goto-char start-heading) + (when folded-heading + (goto-char folded-heading) (org-flag-subtree t)) nil))))) (defun org-decrypt-entry () "Decrypt the content of the current headline." (interactive) - (require 'epg) - (unless (org-before-first-heading-p) - (org-with-wide-buffer - (org-back-to-heading t) - (let ((heading-point (point)) - (heading-was-invisible-p - (save-excursion - (outline-end-of-heading) - (org-invisible-p)))) - (org-end-of-meta-data) - (when (looking-at "-----BEGIN PGP MESSAGE-----") - (org-crypt-check-auto-save) - (setq-local epg-context (epg-make-context nil t t)) - (let* ((end (save-excursion - (search-forward "-----END PGP MESSAGE-----") - (line-beginning-position 2))) - (encrypted-text (buffer-substring-no-properties (point) end)) - (decrypted-text - (decode-coding-string - (epg-decrypt-string epg-context encrypted-text) - 'utf-8))) - ;; Delete region starting just before point, because the - ;; outline property starts at the \n of the heading. - (delete-region (1- (point)) end) - ;; Store a checksum of the decrypted and the encrypted - ;; text value. This allows reusing the same encrypted text - ;; if the text does not change, and therefore avoid a - ;; re-encryption process. - (insert "\n" (propertize decrypted-text - 'org-crypt-checksum (sha1 decrypted-text) - 'org-crypt-key (org-crypt-key-for-heading) - 'org-crypt-text encrypted-text)) - (when heading-was-invisible-p - (goto-char heading-point) - (org-flag-subtree t)) - nil)))))) + (pcase (org-at-encrypted-entry-p) + (`(,beg . ,end) + (require 'epg) + (setq-local epg-context (epg-make-context nil t t)) + (org-with-point-at beg + (org-crypt-check-auto-save) + (let* ((folded-heading + (and (org-invisible-p) + (save-excursion + (org-previous-visible-heading 1) + (point)))) + (encrypted-text (org-crypt--encrypted-text beg end)) + (decrypted-text + (decode-coding-string + (epg-decrypt-string epg-context encrypted-text) + 'utf-8))) + ;; Delete region starting just before point, because the + ;; outline property starts at the \n of the heading. + (delete-region (1- (point)) end) + ;; Store a checksum of the decrypted and the encrypted text + ;; value. This allows reusing the same encrypted text if the + ;; text does not change, and therefore avoid a re-encryption + ;; process. + (insert "\n" + (propertize decrypted-text + 'org-crypt-checksum (sha1 decrypted-text) + 'org-crypt-key (org-crypt-key-for-heading) + 'org-crypt-text encrypted-text)) + (when folded-heading + (goto-char folded-heading) + (org-flag-subtree t)) + nil))) + (_ nil))) (defun org-encrypt-entries () "Encrypt all top-level entries in the current buffer." @@ -258,14 +290,6 @@ Assume `epg-context' is set." (cdr (org-make-tags-matcher org-crypt-tag-matcher)) org--matcher-tags-todo-only))) -(defun org-at-encrypted-entry-p () - "Is the current entry encrypted?" - (unless (org-before-first-heading-p) - (save-excursion - (org-back-to-heading t) - (search-forward "-----BEGIN PGP MESSAGE-----" - (save-excursion (outline-next-heading)) t)))) - (defun org-crypt-use-before-save-magic () "Add a hook to automatically encrypt entries before a file is saved to disk." (add-hook |