Commit 9df72ecb authored by Lars Ingebrigtsen's avatar Lars Ingebrigtsen

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.
parent 3f30d98a
...@@ -110,6 +110,7 @@ a future Emacs interpreter will be able to use it.") ...@@ -110,6 +110,7 @@ a future Emacs interpreter will be able to use it.")
;; These macros are defined here so that they ;; These macros are defined here so that they
;; can safely be used in init files. ;; can safely be used in init files.
;;;###autoload
(defmacro cl-incf (place &optional x) (defmacro cl-incf (place &optional x)
"Increment PLACE by X (1 by default). "Increment PLACE by X (1 by default).
PLACE may be a symbol, or any generalized variable allowed by `setf'. PLACE may be a symbol, or any generalized variable allowed by `setf'.
......
...@@ -102,16 +102,15 @@ encryption is used." ...@@ -102,16 +102,15 @@ encryption is used."
(apply operation args))) (apply operation args)))
(defun epa-file-decode-and-insert (string file visit beg end replace) (defun epa-file-decode-and-insert (string file visit beg end replace)
(if (fboundp 'decode-coding-inserted-region) (save-restriction
(save-restriction (narrow-to-region (point) (point))
(narrow-to-region (point) (point)) (insert string)
(insert string) (decode-coding-inserted-region
(decode-coding-inserted-region (point-min) (point-max)
(point-min) (point-max) (substring file 0 (string-match epa-file-name-regexp file))
(substring file 0 (string-match epa-file-name-regexp file)) visit beg end replace)
visit beg end replace)) (goto-char (point-max))
(insert (epa-file--decode-coding-string string (or coding-system-for-read (- (point-max) (point-min))))
'undecided)))))
(defvar epa-file-error nil) (defvar epa-file-error nil)
(defun epa-file--find-file-not-found-function () (defun epa-file--find-file-not-found-function ()
...@@ -147,8 +146,6 @@ encryption is used." ...@@ -147,8 +146,6 @@ encryption is used."
(format "Decrypting %s" file))) (format "Decrypting %s" file)))
(unwind-protect (unwind-protect
(progn (progn
(if replace
(goto-char (point-min)))
(condition-case error (condition-case error
(setq string (epg-decrypt-file context local-file nil)) (setq string (epg-decrypt-file context local-file nil))
(error (error
...@@ -187,12 +184,11 @@ encryption is used." ...@@ -187,12 +184,11 @@ encryption is used."
;; really edit the buffer. ;; really edit the buffer.
(let ((buffer-file-name (let ((buffer-file-name
(if visit nil buffer-file-name))) (if visit nil buffer-file-name)))
(save-restriction (setq length
(narrow-to-region (point) (point)) (if replace
(epa-file-decode-and-insert string file visit beg end replace) (epa-file--replace-text string file visit beg end)
(setq length (- (point-max) (point-min)))) (epa-file-decode-and-insert
(if replace string file visit beg end replace))))
(delete-region (point) (point-max))))
(if visit (if visit
(set-visited-file-modtime)))) (set-visited-file-modtime))))
(if (and local-copy (if (and local-copy
...@@ -201,6 +197,38 @@ encryption is used." ...@@ -201,6 +197,38 @@ encryption is used."
(list file length))) (list file length)))
(put 'insert-file-contents 'epa-file 'epa-file-insert-file-contents) (put 'insert-file-contents 'epa-file 'epa-file-insert-file-contents)
(defun epa-file--replace-text (string file visit beg end)
;; The idea here is that we want to replace the text in the buffer
;; (for instance, for a `revert-buffer'), but we want to touch as
;; little of the text as possible. So we compare the new and the
;; old text and only starts replacing when the text changes.
(let ((orig-point (point))
new-start length)
(goto-char (point-max))
(setq new-start (point))
(setq length
(epa-file-decode-and-insert
string file visit beg end t))
(if (equal (buffer-substring (point-min) new-start)
(buffer-substring new-start (point-max)))
;; The new text is equal to the old, so just keep the old.
(delete-region new-start (point-max))
;; Compute the region the hard way.
(let ((p1 (point-min))
(p2 new-start))
(while (and (< p1 new-start)
(< p2 (point-max))
(eql (char-after p1) (char-after p2)))
(cl-incf p1)
(cl-incf p2))
(delete-region new-start p2)
(delete-region p1 new-start)))
;; Restore point, if possible.
(if (< orig-point (point-max))
(goto-char orig-point)
(goto-char (point-max)))
length))
(defun epa-file-write-region (start end file &optional append visit lockname (defun epa-file-write-region (start end file &optional append visit lockname
mustbenew) mustbenew)
(if append (if append
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment