From 8b4a6a722a3982024fc87b26dbc7ef7e2043f6e1 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 4 Oct 2021 13:15:41 +0200 Subject: [PATCH] Add new command 'ensure-empty-lines'. * doc/lispref/text.texi (Commands for Insertion): Document it. * lisp/emacs-lisp/subr-x.el (ensure-empty-lines): New command. --- doc/lispref/text.texi | 13 ++++++++++ etc/NEWS | 5 ++++ lisp/emacs-lisp/subr-x.el | 26 +++++++++++++++++++ test/lisp/emacs-lisp/subr-x-tests.el | 38 ++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 41b3138a0dd..1e062be2c64 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -599,6 +599,19 @@ This command indents to the left margin if that is not zero. The value returned is @code{nil}. @end deffn +@deffn Command ensure-empty-lines &optional number-of-empty-lines +This command can be used to ensure that you have a specific number of +empty lines before point. (An ``empty line'' is here defined as a +line with no characters on it---a line with space characters isn't an +empty line.) It defaults to ensuring that there's a single empty line +before point. + +If point isn't at the beginning of a line, a newline character is +inserted first. If there's more empty lines before point than +specified, the number of empty lines is reduced. Otherwise it's +increased to the specified number. +@end deffn + @defvar overwrite-mode This variable controls whether overwrite mode is in effect. The value should be @code{overwrite-mode-textual}, @code{overwrite-mode-binary}, diff --git a/etc/NEWS b/etc/NEWS index b039310afa8..7b4a29e1b66 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -56,6 +56,11 @@ This change also affects 'cl-macrolet', 'cl-flet*' and This can be set to nil to inhibit translating upper case keys to lower case keys. ++++ +** New command 'ensure-empty-lines'. +This command increases (or decreases) the number of empty lines before +point. + * Changes in Specialized Modes and Packages in Emacs 29.1 diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 91ebbf9fb92..ecd3ca831e8 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -412,6 +412,32 @@ and return the value found in PLACE instead." ,(funcall setter val) ,val))))) +;;;###autoload +(defun ensure-empty-lines (&optional lines) + "Ensure that there's LINES number of empty lines before point. +If LINES is nil or missing, a this ensures that there's a single +empty line before point. + +Interactively, this command uses the numerical prefix for LINES. + +If there's already more empty lines before point than LINES, the +number of blank lines will be reduced. + +If point is not at the beginning of a line, a newline character +is inserted before adjusting the number of empty lines." + (interactive "p") + (unless (bolp) + (insert "\n")) + (let ((lines (or lines 1)) + (start (save-excursion + (if (re-search-backward "[^\n]" nil t) + (+ (point) 2) + (point-min))))) + (cond + ((> (- (point) start) lines) + (delete-region (point) (- (point) (- (point) start lines)))) + ((< (- (point) start) lines) + (insert (make-string (- lines (- (point) start)) ?\n)))))) (provide 'subr-x) diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index 1d19496ba44..f9cfea888c7 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -638,5 +638,43 @@ (should (equal (string-chop-newline "foo\nbar\n") "foo\nbar")) (should (equal (string-chop-newline "foo\nbar") "foo\nbar"))) +(ert-deftest subr-ensure-empty-lines () + (should + (equal + (with-temp-buffer + (insert "foo") + (goto-char (point-min)) + (ensure-empty-lines 2) + (buffer-string)) + "\n\nfoo")) + (should + (equal + (with-temp-buffer + (insert "foo") + (ensure-empty-lines 2) + (buffer-string)) + "foo\n\n\n")) + (should + (equal + (with-temp-buffer + (insert "foo\n") + (ensure-empty-lines 2) + (buffer-string)) + "foo\n\n\n")) + (should + (equal + (with-temp-buffer + (insert "foo\n\n\n\n\n") + (ensure-empty-lines 2) + (buffer-string)) + "foo\n\n\n")) + (should + (equal + (with-temp-buffer + (insert "foo\n\n\n") + (ensure-empty-lines 0) + (buffer-string)) + "foo\n"))) + (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.39.5