From 1ee7f3bc793c9d0052a2e4c0f3b5ca077e32ebd9 Mon Sep 17 00:00:00 2001 From: Albert Peschar Date: Sun, 7 Feb 2021 18:50:31 +0200 Subject: [PATCH] Fix infinite loop with rebinding after-save-hook (fixes #27) (#28) * 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 --- CHANGELOG.md | 3 +++ apheleia.el | 29 +++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b474ac..ee2768f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/apheleia.el b/apheleia.el index 303c07a..8f1e195 100644 --- a/apheleia.el +++ b/apheleia.el @@ -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. @@ -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