branch: scratch/editorconfig
commit 5e25a51e2591ca19d034347dafaa3f32cce9367e
Author: Stefan Monnier <monn...@iro.umontreal.ca>
Commit: Stefan Monnier <monn...@iro.umontreal.ca>

    Don't hook into `read-only-mode-hook`
    
    Don't re-set variables just because `read-only-mode` is (de)activated,
    and with Emacs-30's hooks it would be even less natural to do.
    Also `buffer-read-only` can change without calling `read-only-mode`,
    so better test it dynamically when we try to trim whitespace.
    
    * lisp/editorconfig.el (editorconfig--delete-trailing-whitespace):
    New function.
    (editorconfig-set-trailing-ws): Use it.  Use `pcase`.
    Also prefer `before-save-hook` and use `add/remove-hook` to
    manipulate hooks, like god intended.
    Don't test `buffer-read-only` any more.
    (editorconfig-mode): Don't hook into `read-only-mode-hook` any more.
    
    * ert-tests/editorconfig-tests.el (test-trim-trailing-ws): Adjust the
    test accordingly.
---
 editorconfig.el                 | 34 ++++++++++++++++------------------
 ert-tests/editorconfig-tests.el | 16 ++++++++++------
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/editorconfig.el b/editorconfig.el
index 6e215ce23d..029f99e148 100644
--- a/editorconfig.el
+++ b/editorconfig.el
@@ -596,24 +596,23 @@ to non-nil when FINAL-NEWLINE is true."
      (setq-local require-final-newline      nil)
      (setq-local mode-require-final-newline nil))))
 
+(defun editorconfig--delete-trailing-whitespace ()
+  "Call `delete-trailing-whitespace' unless the buffer is read-only."
+  (unless buffer-read-only (delete-trailing-whitespace)))
+
 (defun editorconfig-set-trailing-ws (trim-trailing-ws)
-  "Set up trimming of trailing whitespace at end of lines by TRIM-TRAILING-WS."
-  (make-local-variable 'write-file-functions) ;; just current buffer
-  (when (and (equal trim-trailing-ws "true")
-             (not buffer-read-only))
-    ;; when true we push delete-trailing-whitespace (emacs > 21)
-    ;; to write-file-functions
-    (if editorconfig-trim-whitespaces-mode
-        (funcall editorconfig-trim-whitespaces-mode 1)
-      (add-to-list 'write-file-functions 'delete-trailing-whitespace)))
-  (when (or (equal trim-trailing-ws "false")
-            buffer-read-only)
-    ;; when false we remove every delete-trailing-whitespace
-    ;; from write-file-functions
-    (when editorconfig-trim-whitespaces-mode
-      (funcall editorconfig-trim-whitespaces-mode 0))
-    (setq write-file-functions
-          (remove 'delete-trailing-whitespace write-file-functions))))
+  (pcase trim-trailing-ws
+    ("true"
+     (if editorconfig-trim-whitespaces-mode
+         (funcall editorconfig-trim-whitespaces-mode 1)
+       (add-hook 'before-save-hook
+                 #'editorconfig--delete-trailing-whitespace nil t)))
+    ("false"
+     (when editorconfig-trim-whitespaces-mode
+       (funcall editorconfig-trim-whitespaces-mode 0))
+     (remove-hook 'before-save-hook
+                  #'editorconfig--delete-trailing-whitespace t))))
+
 
 (defun editorconfig-set-line-length (length)
   "Set the max line length (`fill-column') to LENGTH."
@@ -851,7 +850,6 @@ To disable EditorConfig in some buffers, modify
   :lighter editorconfig-mode-lighter
   (let ((modehooks '(prog-mode-hook
                      text-mode-hook
-                     read-only-mode-hook
                      ;; Some modes call `kill-all-local-variables' in their 
init
                      ;; code, which clears some values set by editorconfig.
                      ;; For those modes, editorconfig-apply need to be called
diff --git a/ert-tests/editorconfig-tests.el b/ert-tests/editorconfig-tests.el
index 75da5ebade..82577f8518 100644
--- a/ert-tests/editorconfig-tests.el
+++ b/ert-tests/editorconfig-tests.el
@@ -102,12 +102,16 @@
 (ert-deftest test-trim-trailing-ws nil
   (editorconfig-mode 1)
   (with-visit-file (concat editorconfig-ert-dir "trim.txt")
-    (should (memq 'delete-trailing-whitespace
-                  write-file-functions)))
-  (with-visit-file (concat editorconfig-ert-dir "trim.txt")
-    (read-only-mode 1)
-    (should (not (memq 'delete-trailing-whitespace
-                       write-file-functions))))
+    (should (memq #'editorconfig--delete-trailing-whitespace
+                  before-save-hook)))
+  ;; FIXME: We don't hook into `read-only-mode', so instead we should
+  ;; make a more thorough test that saves the file after making the buffer
+  ;; read-only and makes sure it does not trim the trailing-ws of the
+  ;; buffer/file.
+  ;;(with-visit-file (concat editorconfig-ert-dir "trim.txt")
+  ;;  (read-only-mode 1)
+  ;;  (should (not (memq #'editorconfig--delete-trailing-whitespace
+  ;;                     before-save-hook))))
   (editorconfig-mode -1))
 
 (ert-deftest test-charset nil

Reply via email to