From: Björn Lindström Date: Tue, 11 Jun 2024 17:49:55 +0000 (+0200) Subject: Make whitespace.el's cleanup add missing final newline X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=605f49a2b028533d664983fbd8291143a4ee25ff;p=emacs.git Make whitespace.el's 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'. (Bug#71499) * etc/NEWS: Announce the change in behavior. (cherry picked from commit 2a7a7c6f697ac9699dec8b09f1cd2051247b2b45) --- 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 @@ The problems cleaned up are: 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 @@ documentation." ((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 @@ buffer's content." (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.