From a6ca7984df3eec80e8a36ded73d068073d9a5a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Lindstr=C3=B6m?= Date: Tue, 11 Jun 2024 19:49:55 +0200 Subject: [PATCH] Make whitespace.el cleanup add missing final newline * lisp/whitespace.el (whitespace-cleanup-region): if cleaning up at end of file, add missing newline if indicated by whitespace-style. --- etc/NEWS | 6 ++++++ lisp/whitespace.el | 16 +++++++++++++++- test/lisp/whitespace-tests.el | 15 ++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index af32a93d9c4..9f61a4aa4ce 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -36,6 +36,12 @@ applies, and please also update docstrings as needed. * Changes in Specialized Modes and Packages in Emacs 31.1 +--- +** Whitespace +'whitespace-cleanup' now adds missing newline at end of file If +'whitespace-style' includes 'missing-newline-at-eof (which is the +default), the 'whitespace-cleanup' function will fix this when run. + * New Modes and Packages in Emacs 31.1 diff --git a/lisp/whitespace.el b/lisp/whitespace.el index bc23a8794eb..28d131b054c 100644 --- a/lisp/whitespace.el +++ b/lisp/whitespace.el @@ -1465,6 +1465,11 @@ defun whitespace-cleanup-region If `whitespace-style' includes the value `space-after-tab::space', replace TABs by SPACEs. +5. missing newline at end of file. + If `whitespace-style' includes the value `missing-newline-at-eof', + and the cleanup region includes the end of file, add a final newline + if it is not there already. + See `whitespace-style', `indent-tabs-mode' and `tab-width' for documentation." (interactive "@r") @@ -1545,7 +1550,16 @@ defun whitespace-cleanup-region ((memq 'space-before-tab::space whitespace-style) (whitespace-replace-action 'untabify rstart rend - whitespace-space-before-tab-regexp 2)))) + whitespace-space-before-tab-regexp 2))) + ;; PROBLEM 5: missing newline at end of file + (and (memq 'missing-newline-at-eof whitespace-style) + (> (point-max) (point-min)) + (= (point-max) (without-restriction (point-max))) + (/= (char-before (point-max)) ?\n) + (not (and (eq selective-display t) + (= (char-before (point-max)) ?\r))) + (goto-char (point-max)) + (ignore-errors (insert "\n")))) (set-marker rend nil)))) ; point marker to nowhere diff --git a/test/lisp/whitespace-tests.el b/test/lisp/whitespace-tests.el index 73c7e742ec5..bd35b3ac9f3 100644 --- a/test/lisp/whitespace-tests.el +++ b/test/lisp/whitespace-tests.el @@ -8,7 +8,6 @@ ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. - ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -94,6 +93,20 @@ defun whitespace-tests--cleanup-string (should (equal (whitespace-tests--cleanup-string "a \n\t \n\n") "a \n")))) +(ert-deftest whitespace-cleanup-missing-newline-at-eof () + (let ((whitespace-style '(empty missing-newline-at-eof))) + (should (equal (whitespace-tests--cleanup-string "") + "")) + (should (equal (whitespace-tests--cleanup-string "a") + "a\n")) + (should (equal (whitespace-tests--cleanup-string "a\n\t") + "a\n")) + (should (equal (whitespace-tests--cleanup-string "a\n\t ") + "a\n")) + (should (equal (whitespace-tests--cleanup-string "a\n\t ") + "a\n")) + (should (equal (whitespace-tests--cleanup-string "\n\t") + "")))) ;; We cannot call whitespace-mode because it will do nothing in batch ;; mode. So we call its innards instead. -- 2.45.2