Emacs: Clean Empty Lines 📜
Here's 2 commands that remove repeated blank lines and delete trailing white space.
Clean White Space
(defun xah-clean-whitespace (&optional Begin End) "Delete trailing whitespace, and replace repeated blank lines to just 1. Only space and tab is considered whitespace here. Works on whole buffer or selection, respects `narrow-to-region'. URL `http://xahlee.info/emacs/emacs/elisp_compact_empty_lines.html' Created: 2017-09-22 Version: 2025-05-04" (interactive) (let (xbeg xend) (seq-setq (xbeg xend) (if (and Begin End) (list Begin End) (if (region-active-p) (list (region-beginning) (region-end)) (list (point-min) (point-max))))) (save-excursion (save-restriction (narrow-to-region xbeg xend) (progn (goto-char (point-min)) (while (re-search-forward "[ \t]+\n" nil t) (replace-match "\n"))) (progn (goto-char (point-min)) (while (re-search-forward "\n\n\n+" nil t) (replace-match "\n\n"))) (progn (goto-char (point-max)) (while (eq (char-before) 32) (delete-char -1)))))) (message "done xah-clean-whitespace"))
You can make this automatic. Every time the file is saved, whitespaces are cleaned.
(add-hook 'before-save-hook 'xah-clean-whitespace)
Clean Empty Lines
(defun xah-clean-empty-lines () "Replace repeated blank lines to just 1, in whole buffer or selection. Respects `narrow-to-region'. URL `http://xahlee.info/emacs/emacs/elisp_compact_empty_lines.html' Created: 2017-09-22 Version: 2020-09-08" (interactive) (let (xbegin xend) (if (region-active-p) (setq xbegin (region-beginning) xend (region-end)) (setq xbegin (point-min) xend (point-max))) (save-excursion (save-restriction (narrow-to-region xbegin xend) (progn (goto-char (point-min)) (while (re-search-forward "\n\n\n+" nil 1) (replace-match "\n\n")))))))
Whitespace Sensitive Files
Be careful on whitespace sensitive language or file format.
- For Python, removing trailing whitespace is safe. Compacting empty lines is also safe. (not considering multi-line strings.)
- For markdown, removing trailing whitespace will break hard returns
<br />. (thanks to Heow Goodman )
If you work with these languages, you probably want to add a check in your function. Try to modify the code. Hint: check on the variable major-mode, or check file name extension.