aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-08-30 12:20:30 +0200
committerLars Ingebrigtsen2019-09-04 15:20:00 +0200
commit9df72ecb6339110a0380c6faf75e7e93025bb26a (patch)
tree8f46c3e2c93d4ec1fa370b6f9b7944d1878d5887
parent3f30d98af9401562c68f3a0388cf16593eb572e5 (diff)
downloademacs-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.el1
-rw-r--r--lisp/epa-file.el64
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).
115PLACE may be a symbol, or any generalized variable allowed by `setf'. 116PLACE 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