diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 7b9a4e372..c4e1263bf 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -1158,6 +1158,12 @@ as the function can also act on objects. *** ~org-export-get-parent-element~ is renamed to ~org-element-parent-element~ and moved to =lisp/org-element.el= +*** ~org-insert-heading~ optional argument =TOP= is now =LEVEL= + +A numeric value forces a heading at that level to be inserted. For +backwards compatibility, non-numeric non-nil values insert level 1 +headings as before. + ** Miscellaneous *** =org-crypt.el= now applies initial visibility settings to decrypted entries diff --git a/lisp/org.el b/lisp/org.el index ce64be50d..1d33e6de0 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6388,7 +6388,7 @@ headline instead of current one." (`(heading . ,value) value) (_ nil))) -(defun org-insert-heading (&optional arg invisible-ok top) +(defun org-insert-heading (&optional arg invisible-ok level) "Insert a new heading or an item with the same depth at point. If point is at the beginning of a heading, insert a new heading @@ -6417,12 +6417,19 @@ When INVISIBLE-OK is set, stop at invisible headlines when going back. This is important for non-interactive uses of the command. -When optional argument TOP is non-nil, insert a level 1 heading, -unconditionally." +When optional argument LEVEL is a number, insert a heading at +that level. For backwards compatibility, when LEVEL is non-nil +but not a number, insert a level-1 heading." (interactive "P") (let* ((blank? (org--blank-before-heading-p (equal arg '(16)))) - (level (org-current-level)) - (stars (make-string (if (and level (not top)) level 1) ?*))) + (current-level (org-current-level)) + (num-stars (or + ;; Backwards compat: if LEVEL non-nil, level is 1 + (and level (if (wholenump level) level 1)) + current-level + ;; This `1' is for when before first headline + 1)) + (stars (make-string num-stars ?*))) (cond ((or org-insert-heading-respect-content (member arg '((4) (16))) @@ -6431,7 +6438,7 @@ unconditionally." ;; Position point at the location of insertion. Make sure we ;; end up on a visible headline if INVISIBLE-OK is nil. (org-with-limited-levels - (if (not level) (outline-next-heading) ;before first headline + (if (not current-level) (outline-next-heading) ;before first headline (org-back-to-heading invisible-ok) (when (equal arg '(16)) (org-up-heading-safe)) (org-end-of-subtree invisible-ok 'to-heading))) @@ -6444,7 +6451,7 @@ unconditionally." (org-before-first-heading-p))) (insert "\n") (backward-char)) - (when (and (not level) (not (eobp)) (not (bobp))) + (when (and (not current-level) (not (eobp)) (not (bobp))) (when (org-at-heading-p) (insert "\n")) (backward-char)) (unless (and blank? (org-previous-line-empty-p)) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 2e4516536..830d0aaa3 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -1980,8 +1980,30 @@ CLOCK: [2022-09-17 sam. 11:00]--[2022-09-17 sam. 11:46] => 0:46" (let ((org-insert-heading-respect-content nil)) (org-insert-heading '(16))) (buffer-string)))) - ;; When optional TOP-LEVEL argument is non-nil, always insert - ;; a level 1 heading. + ;; When optional LEVEL argument is a number, insert a heading at + ;; that level. + (should + (equal "* H1\n** H2\n* " + (org-test-with-temp-text "* H1\n** H2" + (org-insert-heading nil nil 1) + (buffer-string)))) + (should + (equal "* H1\n** H2\n** " + (org-test-with-temp-text "* H1\n** H2" + (org-insert-heading nil nil 2) + (buffer-string)))) + (should + (equal "* H1\n** H2\n*** " + (org-test-with-temp-text "* H1\n** H2" + (org-insert-heading nil nil 3) + (buffer-string)))) + (should + (equal "* H1\n- item\n* " + (org-test-with-temp-text "* H1\n- item" + (org-insert-heading nil nil 1) + (buffer-string)))) + ;; When optional LEVEL argument is non-nil, always insert a level 1 + ;; heading. (should (equal "* H1\n** H2\n* " (org-test-with-temp-text "* H1\n** H2"