aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2025-05-05 11:55:29 -0400
committerStefan Monnier2025-05-12 12:39:16 -0400
commit8a19c249f813e9f3830308e40f0205d7665f78a3 (patch)
treeea978b12167b0a0aad40b7971bfb0adb134916d0
parentd11570d80ee18932ffb0ceed552313ada2879bcb (diff)
downloademacs-8a19c249f813e9f3830308e40f0205d7665f78a3.tar.gz
emacs-8a19c249f813e9f3830308e40f0205d7665f78a3.zip
simple.el (delete-trailing-whitespace-mode): New minor mode (bug#78264)
Partly motivated by bug#78097. * lisp/simple.el (delete-trailing-whitespace-if-possible): New function. (delete-trailing-whitespace-mode): New minor mode. * lisp/editorconfig.el (editorconfig-trim-whitespaces-mode): Change default to `delete-trailing-whitespace-mode`. (editorconfig--get-trailing-ws): Simplify accordingly. (editorconfig--add-hook-safe-p): Delete function. Don't touch `safe-local-eval-function` any more.
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/editorconfig.el38
-rw-r--r--lisp/simple.el15
3 files changed, 30 insertions, 27 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 2dca61740d4..612d2d841cb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2059,6 +2059,10 @@ is bound to 'C-l' in the calendar buffer.
2059 2059
2060* New Modes and Packages in Emacs 31.1 2060* New Modes and Packages in Emacs 31.1
2061 2061
2062** New minor mode 'delete-trailing-whitespace-mode'.
2063A simple buffer-local mode that runs 'delete-trailing-whitespace'
2064before saving the buffer.
2065
2062** New major mode 'conf-npmrc-mode'. 2066** New major mode 'conf-npmrc-mode'.
2063A major mode based on 'conf-mode' for editing ".npmrc" files. 2067A major mode based on 'conf-mode' for editing ".npmrc" files.
2064 2068
diff --git a/lisp/editorconfig.el b/lisp/editorconfig.el
index 7cdd79fa3b0..bfc8ef46ed3 100644
--- a/lisp/editorconfig.el
+++ b/lisp/editorconfig.el
@@ -277,13 +277,13 @@ a list of settings in the form (VARIABLE . VALUE)."
277 :version "30.1" 277 :version "30.1"
278 :risky t) 278 :risky t)
279 279
280(defcustom editorconfig-trim-whitespaces-mode nil 280(defcustom editorconfig-trim-whitespaces-mode #'delete-trailing-whitespace-mode
281 "Buffer local minor-mode to use to trim trailing whitespaces. 281 "Buffer local minor-mode to use to trim trailing whitespaces.
282 282
283If set, enable that mode when `trim_trailing_whitespace` is set to true. 283If set, enable that mode when `trim_trailing_whitespace` is set to true.
284Otherwise, use `delete-trailing-whitespace'." 284Otherwise, use `delete-trailing-whitespace'."
285 :version "30.1" 285 :version "30.1"
286 :type 'symbol) 286 :type 'function)
287 287
288(defvar-local editorconfig-properties-hash nil 288(defvar-local editorconfig-properties-hash nil
289 "Hash object of EditorConfig properties that was enabled for current buffer. 289 "Hash object of EditorConfig properties that was enabled for current buffer.
@@ -542,33 +542,17 @@ This function will revert buffer when the coding-system has been changed."
542 "Call `delete-trailing-whitespace' unless the buffer is read-only." 542 "Call `delete-trailing-whitespace' unless the buffer is read-only."
543 (unless buffer-read-only (delete-trailing-whitespace))) 543 (unless buffer-read-only (delete-trailing-whitespace)))
544 544
545;; Arrange for our (eval . (add-hook ...)) "local var" to be considered safe.
546(defun editorconfig--add-hook-safe-p (exp)
547 (equal exp '(add-hook 'before-save-hook
548 #'editorconfig--delete-trailing-whitespace nil t)))
549(let ((predicates (get 'add-hook 'safe-local-eval-function)))
550 (when (functionp predicates)
551 (setq predicates (list predicates)))
552 (unless (memq #'editorconfig--add-hook-safe-p predicates)
553 (put 'add-hook 'safe-local-eval-function #'editorconfig--add-hook-safe-p)))
554
555(defun editorconfig--get-trailing-ws (props) 545(defun editorconfig--get-trailing-ws (props)
556 "Get vars to trim of trailing whitespace according to PROPS." 546 "Get vars to trim of trailing whitespace according to PROPS."
557 (pcase (gethash 'trim_trailing_whitespace props) 547 (let ((fun (or editorconfig-trim-whitespaces-mode
558 ("true" 548 #'delete-trailing-whitespace-mode)))
559 `((eval 549 (pcase (gethash 'trim_trailing_whitespace props)
560 . ,(if editorconfig-trim-whitespaces-mode 550 ("true" `((eval . (,fun 1))))
561 `(,editorconfig-trim-whitespaces-mode 1) 551 ("false"
562 '(add-hook 'before-save-hook 552 ;; Just do it right away rather than return a (VAR . VAL), which
563 #'editorconfig--delete-trailing-whitespace nil t))))) 553 ;; would be probably more trouble than it's worth.
564 ("false" 554 (funcall fun 0)
565 ;; Just do it right away rather than return a (VAR . VAL), which 555 nil))))
566 ;; would be probably more trouble than it's worth.
567 (when editorconfig-trim-whitespaces-mode
568 (funcall editorconfig-trim-whitespaces-mode 0))
569 (remove-hook 'before-save-hook
570 #'editorconfig--delete-trailing-whitespace t)
571 nil)))
572 556
573(defun editorconfig--get-line-length (props) 557(defun editorconfig--get-line-length (props)
574 "Get the max line length (`fill-column') to PROPS." 558 "Get the max line length (`fill-column') to PROPS."
diff --git a/lisp/simple.el b/lisp/simple.el
index 486092de2c8..f686907ad68 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -888,6 +888,21 @@ buffer if the variable `delete-trailing-lines' is non-nil."
888 ;; Return nil for the benefit of `write-file-functions'. 888 ;; Return nil for the benefit of `write-file-functions'.
889 nil) 889 nil)
890 890
891(defun delete-trailing-whitespace-if-possible ()
892 "Call `delete-trailing-whitespace' unless the buffer is read-only."
893 (unless buffer-read-only (delete-trailing-whitespace)))
894
895(define-minor-mode delete-trailing-whitespace-mode
896 "Delete trailing whitespace before saving the current buffer."
897 :global nil
898 (cond
899 (delete-trailing-whitespace-mode
900 (add-hook 'before-save-hook
901 #'delete-trailing-whitespace-if-possible nil t))
902 (t
903 (remove-hook 'before-save-hook
904 #'delete-trailing-whitespace-if-possible t))))
905
891(defun newline-and-indent (&optional arg) 906(defun newline-and-indent (&optional arg)
892 "Insert a newline, then indent according to major mode. 907 "Insert a newline, then indent according to major mode.
893Indentation is done using the value of `indent-line-function'. 908Indentation is done using the value of `indent-line-function'.