[#226] Use lexical variable for saved buffer hash (#234)

Should help with https://github.com/radian-software/apheleia/issues/226
although there is a second problem related to performance also reported
in that thread, which would not be helped with this.

Mostly indentation changes.
This commit is contained in:
Radon Rosborough 2023-10-29 15:39:42 -07:00 committed by GitHub
parent 5bade7a734
commit 7d3b061e3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -44,9 +44,6 @@
(buffer-hash) (buffer-hash)
(md5 (current-buffer)))) (md5 (current-buffer))))
(defvar apheleia--buffer-hash nil
"Return value of `buffer-hash' when formatter started running.")
(defun apheleia--disallowed-p () (defun apheleia--disallowed-p ()
"Return an error message if Apheleia cannot be run, else nil." "Return an error message if Apheleia cannot be run, else nil."
(when (and buffer-file-name (when (and buffer-file-name
@ -96,33 +93,41 @@ changes), CALLBACK, if provided, is invoked with no arguments."
;; error on `post-command-hook'. We already took care of throwing ;; error on `post-command-hook'. We already took care of throwing
;; `user-error' on interactive usage above. ;; `user-error' on interactive usage above.
(unless (apheleia--disallowed-p) (unless (apheleia--disallowed-p)
(setq-local apheleia--buffer-hash (apheleia--buffer-hash)) ;; It's important to store the saved buffer hash in a lexical
(let ((cur-buffer (current-buffer)) ;; variable rather than a dynamic (global) one, else multiple
(remote (file-remote-p (or buffer-file-name ;; concurrent invocations of `apheleia-format-buffer' can
default-directory)))) ;; overwrite each other, and get the wrong results about whether
(apheleia--run-formatters ;; the buffer was actually modified since the formatting
formatters ;; operation started, leading to data loss.
cur-buffer ;;
remote ;; https://github.com/radian-software/apheleia/issues/226
(lambda (formatted-buffer) (let ((saved-buffer-hash (apheleia--buffer-hash)))
(when (buffer-live-p cur-buffer) (let ((cur-buffer (current-buffer))
(with-current-buffer cur-buffer (remote (file-remote-p (or buffer-file-name
;; Short-circuit. default-directory))))
(when (apheleia--run-formatters
(equal formatters
apheleia--buffer-hash (apheleia--buffer-hash)) cur-buffer
(apheleia--create-rcs-patch remote
cur-buffer formatted-buffer remote (lambda (formatted-buffer)
(lambda (patch-buffer) (when (buffer-live-p cur-buffer)
(when (buffer-live-p cur-buffer) (with-current-buffer cur-buffer
(with-current-buffer cur-buffer ;; Short-circuit.
(when (when
(equal (equal
apheleia--buffer-hash (apheleia--buffer-hash)) saved-buffer-hash (apheleia--buffer-hash))
(apheleia--apply-rcs-patch (apheleia--create-rcs-patch
(current-buffer) patch-buffer) cur-buffer formatted-buffer remote
(when callback (lambda (patch-buffer)
(funcall callback)))))))))))))))) (when (buffer-live-p cur-buffer)
(with-current-buffer cur-buffer
(when
(equal
saved-buffer-hash (apheleia--buffer-hash))
(apheleia--apply-rcs-patch
(current-buffer) patch-buffer)
(when callback
(funcall callback)))))))))))))))))
(defcustom apheleia-post-format-hook nil (defcustom apheleia-post-format-hook nil
"Normal hook run after Apheleia formats a buffer successfully." "Normal hook run after Apheleia formats a buffer successfully."