diff options
| author | Lars Ingebrigtsen | 2019-08-30 12:20:30 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2019-09-04 15:20:00 +0200 |
| commit | 9df72ecb6339110a0380c6faf75e7e93025bb26a (patch) | |
| tree | 8f46c3e2c93d4ec1fa370b6f9b7944d1878d5887 | |
| parent | 3f30d98af9401562c68f3a0388cf16593eb572e5 (diff) | |
| download | emacs-9df72ecb6339110a0380c6faf75e7e93025bb26a.tar.gz emacs-9df72ecb6339110a0380c6faf75e7e93025bb26a.zip | |
Preserve more markers when reverting .gpg files
* lisp/epa-file.el (epa-file--replace-text): Gingerly replace the
text in the buffer to preserve as many markers as possible
(bug#34720). This emulates the behaviour of Finsert_file_contents
more accurately.
(epa-file-decode-and-insert): Remove compat code.
(epa-file-insert-file-contents): Use the new function.
* lisp/emacs-lisp/cl-lib.el (cl-incf): Add autoload cookie.
| -rw-r--r-- | lisp/emacs-lisp/cl-lib.el | 1 | ||||
| -rw-r--r-- | lisp/epa-file.el | 64 |
2 files changed, 47 insertions, 18 deletions
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index c09fcf51eba..ff096918173 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el | |||
| @@ -110,6 +110,7 @@ a future Emacs interpreter will be able to use it.") | |||
| 110 | ;; These macros are defined here so that they | 110 | ;; These macros are defined here so that they |
| 111 | ;; can safely be used in init files. | 111 | ;; can safely be used in init files. |
| 112 | 112 | ||
| 113 | ;;;###autoload | ||
| 113 | (defmacro cl-incf (place &optional x) | 114 | (defmacro cl-incf (place &optional x) |
| 114 | "Increment PLACE by X (1 by default). | 115 | "Increment PLACE by X (1 by default). |
| 115 | PLACE may be a symbol, or any generalized variable allowed by `setf'. | 116 | PLACE may be a symbol, or any generalized variable allowed by `setf'. |
diff --git a/lisp/epa-file.el b/lisp/epa-file.el index d9886d3d67f..c43641aacf3 100644 --- a/lisp/epa-file.el +++ b/lisp/epa-file.el | |||
| @@ -102,16 +102,15 @@ encryption is used." | |||
| 102 | (apply operation args))) | 102 | (apply operation args))) |
| 103 | 103 | ||
| 104 | (defun epa-file-decode-and-insert (string file visit beg end replace) | 104 | (defun epa-file-decode-and-insert (string file visit beg end replace) |
| 105 | (if (fboundp 'decode-coding-inserted-region) | 105 | (save-restriction |
| 106 | (save-restriction | 106 | (narrow-to-region (point) (point)) |
| 107 | (narrow-to-region (point) (point)) | 107 | (insert string) |
| 108 | (insert string) | 108 | (decode-coding-inserted-region |
| 109 | (decode-coding-inserted-region | 109 | (point-min) (point-max) |
| 110 | (point-min) (point-max) | 110 | (substring file 0 (string-match epa-file-name-regexp file)) |
| 111 | (substring file 0 (string-match epa-file-name-regexp file)) | 111 | visit beg end replace) |
| 112 | visit beg end replace)) | 112 | (goto-char (point-max)) |
| 113 | (insert (epa-file--decode-coding-string string (or coding-system-for-read | 113 | (- (point-max) (point-min)))) |
| 114 | 'undecided))))) | ||
| 115 | 114 | ||
| 116 | (defvar epa-file-error nil) | 115 | (defvar epa-file-error nil) |
| 117 | (defun epa-file--find-file-not-found-function () | 116 | (defun epa-file--find-file-not-found-function () |
| @@ -147,8 +146,6 @@ encryption is used." | |||
| 147 | (format "Decrypting %s" file))) | 146 | (format "Decrypting %s" file))) |
| 148 | (unwind-protect | 147 | (unwind-protect |
| 149 | (progn | 148 | (progn |
| 150 | (if replace | ||
| 151 | (goto-char (point-min))) | ||
| 152 | (condition-case error | 149 | (condition-case error |
| 153 | (setq string (epg-decrypt-file context local-file nil)) | 150 | (setq string (epg-decrypt-file context local-file nil)) |
| 154 | (error | 151 | (error |
| @@ -187,12 +184,11 @@ encryption is used." | |||
| 187 | ;; really edit the buffer. | 184 | ;; really edit the buffer. |
| 188 | (let ((buffer-file-name | 185 | (let ((buffer-file-name |
| 189 | (if visit nil buffer-file-name))) | 186 | (if visit nil buffer-file-name))) |
| 190 | (save-restriction | 187 | (setq length |
| 191 | (narrow-to-region (point) (point)) | 188 | (if replace |
| 192 | (epa-file-decode-and-insert string file visit beg end replace) | 189 | (epa-file--replace-text string file visit beg end) |
| 193 | (setq length (- (point-max) (point-min)))) | 190 | (epa-file-decode-and-insert |
| 194 | (if replace | 191 | string file visit beg end replace)))) |
| 195 | (delete-region (point) (point-max)))) | ||
| 196 | (if visit | 192 | (if visit |
| 197 | (set-visited-file-modtime)))) | 193 | (set-visited-file-modtime)))) |
| 198 | (if (and local-copy | 194 | (if (and local-copy |
| @@ -201,6 +197,38 @@ encryption is used." | |||
| 201 | (list file length))) | 197 | (list file length))) |
| 202 | (put 'insert-file-contents 'epa-file 'epa-file-insert-file-contents) | 198 | (put 'insert-file-contents 'epa-file 'epa-file-insert-file-contents) |
| 203 | 199 | ||
| 200 | (defun epa-file--replace-text (string file visit beg end) | ||
| 201 | ;; The idea here is that we want to replace the text in the buffer | ||
| 202 | ;; (for instance, for a `revert-buffer'), but we want to touch as | ||
| 203 | ;; little of the text as possible. So we compare the new and the | ||
| 204 | ;; old text and only starts replacing when the text changes. | ||
| 205 | (let ((orig-point (point)) | ||
| 206 | new-start length) | ||
| 207 | (goto-char (point-max)) | ||
| 208 | (setq new-start (point)) | ||
| 209 | (setq length | ||
| 210 | (epa-file-decode-and-insert | ||
| 211 | string file visit beg end t)) | ||
| 212 | (if (equal (buffer-substring (point-min) new-start) | ||
| 213 | (buffer-substring new-start (point-max))) | ||
| 214 | ;; The new text is equal to the old, so just keep the old. | ||
| 215 | (delete-region new-start (point-max)) | ||
| 216 | ;; Compute the region the hard way. | ||
| 217 | (let ((p1 (point-min)) | ||
| 218 | (p2 new-start)) | ||
| 219 | (while (and (< p1 new-start) | ||
| 220 | (< p2 (point-max)) | ||
| 221 | (eql (char-after p1) (char-after p2))) | ||
| 222 | (cl-incf p1) | ||
| 223 | (cl-incf p2)) | ||
| 224 | (delete-region new-start p2) | ||
| 225 | (delete-region p1 new-start))) | ||
| 226 | ;; Restore point, if possible. | ||
| 227 | (if (< orig-point (point-max)) | ||
| 228 | (goto-char orig-point) | ||
| 229 | (goto-char (point-max))) | ||
| 230 | length)) | ||
| 231 | |||
| 204 | (defun epa-file-write-region (start end file &optional append visit lockname | 232 | (defun epa-file-write-region (start end file &optional append visit lockname |
| 205 | mustbenew) | 233 | mustbenew) |
| 206 | (if append | 234 | (if append |