Skip to content

Commit

Permalink
Fix infinite loop with rebinding after-save-hook (fixes #27) (#28)
Browse files Browse the repository at this point in the history
* Fix infinite loop with rebinding after-save-hook (fixes #27)

* Satisfy linter

* Add docstring for new var

* Update changelog

* apheleia-format-buffer is asynchronous

* Update apheleia.el

Co-authored-by: Radon Rosborough <[email protected]>
  • Loading branch information
apeschar and raxod502 authored Feb 7, 2021
1 parent 8a1e684 commit 1ee7f3b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ The format is based on [Keep a Changelog].

### Bugs fixed
* Prettier now respects `.prettierignore` ([#21]).
* Apheleia's global mode should no longer trigger warnings about a locally
let-bound `after-save-hook` ([#27]).

[#21]: https://github.com/raxod502/apheleia/issues/21
[#27]: https://github.com/raxod502/apheleia/issues/27

## 1.1.1 (released 2020-07-16)
### Formatters
Expand Down
29 changes: 17 additions & 12 deletions apheleia.el
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,7 @@ mark the buffer as visiting FILENAME."
(lambda (format &rest args)
(unless (equal format "Saving file %s...")
(apply message format args)))))
;; Avoid infinite loop.
(let ((after-save-hook
(remq #'apheleia--format-after-save after-save-hook)))
(write-file (or filename buffer-file-name)))))
(write-file (or filename buffer-file-name))))

(defun apheleia--create-rcs-patch (old-buffer new-buffer callback)
"Generate RCS patch from text in OLD-BUFFER to text in NEW-BUFFER.
Expand Down Expand Up @@ -629,19 +626,27 @@ changes), CALLBACK, if provided, is invoked with no arguments."
;; Handle recursive references.
(defvar apheleia-mode)

;; Prevent infinite loop.
(defvar apheleia--format-after-save-in-progress nil
"Prevent apheleia--format-after-save from being called recursively.
This will be locally bound to t while apheleia--format-after-save is
operating, to prevent an infinite loop.")

;; Autoload because the user may enable `apheleia-mode' without
;; loading Apheleia; thus this function may be invoked as an autoload.
;;;###autoload
(defun apheleia--format-after-save ()
"Run code formatter for current buffer if any configured, then save."
(when apheleia-mode
(when-let ((command (apheleia--get-formatter-command)))
(apheleia-format-buffer
command
(lambda ()
(with-demoted-errors "Apheleia: %s"
(apheleia--write-file-silently buffer-file-name)
(run-hooks 'apheleia-post-format-hook)))))))
(unless apheleia--format-after-save-in-progress
(when apheleia-mode
(when-let ((command (apheleia--get-formatter-command)))
(apheleia-format-buffer
command
(lambda ()
(with-demoted-errors "Apheleia: %s"
(let ((apheleia--format-after-save-in-progress t))
(apheleia--write-file-silently buffer-file-name))
(run-hooks 'apheleia-post-format-hook))))))))

;; Use `progn' to force the entire minor mode definition to be copied
;; into the autoloads file, so that the minor mode can be enabled
Expand Down

0 comments on commit 1ee7f3b

Please sign in to comment.