2

I make intensive use of org-mode and it boosts my productivity significantly. But I'm missing the possibility to adjust the space between headings automatically.

On the one hand I want to define the number of lines between headings and subheadings, so that for example headings of the same level are delimited by 1 empty line and headings of different levels by 2.

On the other hand, the text inside headings is to be positioned consistently. It would be ideal If could distinguish between the space that is to be inserted after a heading and the space before. So I can define that the text after a heading starts after 2 lines and the heading after a text has 4 preceding empty lines.

The perfect solution would be If I could add that function to org-cycle-hook.

  • 1
    I've been using a replace-regexp for years and a programmatic sorter (refiles and sorts by four criteria -- alphabetic, by keyword, by priority, by date; and carries forward any uncompleted/overdue tasks) that gets triggered with a yes/no prompt when I pull up the file or when I am lazy and want to switch back to it again (e.g., just pull it up again). Here is an example: (let ((query-replace-lazy-highlight nil)) (replace-regexp "\n+\\*\\* " "\n\n** " nil (point-min) (point-max)) (replace-regexp "\n+\\* " "\n\n\n* " nil (point-min) (point-max))) You can control org-capture new lines. – lawlist Oct 30 '16 at 0:39
  • 1
    See also the customizable variables org-cycle-separator-lines and outline-blank-line that will visually adjust the spacing between headings without altering the content of the buffer. For more information, type M-x describe-variable aka C-h v. – lawlist Oct 30 '16 at 20:14
2

This is trickier than it seemed! Here is some code that seems to do what you want, I think. It only adds lines at the beginning of a heading, and at the end of what I call the heading content (not including subtrees). It adds different numbers of lines at the end depending on what the next heading is.

I briefly tried adding it to the org-cycle-hook, and it seems to work ok. I would make sure you have a backup on files you use this on, since it changes your file! While developing it, I noticed some occasional visibility issues, and issues with the org-element-cache sometimes, and occasionally had to reset it. This version does not seem to have an issue there, but if you see weird behavior it might be related.

(require 'cl)

(defvar org-blank-lines-after-heading 1
  "Number of blank lines to separate a heading from the content.")

(defvar org-blank-lines-after-content (cons 2 4) 
  "Cons cell for the number of blank lines after content in a heading.
The car is for when the next heading is at the same level, and
the cdr is for when the next heading is at a different level.
This is for the body specific to the headline, not counting
subheadings.")

(defun org-format-heading-blank-lines ()
  "Make sure each headline has exactly
`org-blank-lines-after-heading' after the heading, and
`org-blank-lines-after-content' blank lines at the end of its
content. Only works when point is in a headline."
  (interactive)
  (when (org-at-heading-p)
    (let ((current-level (nth 0 (org-heading-components)))
      next-level)
      (save-excursion
    (org-end-of-meta-data)
    ;; chomp blank lines then add what you want back.
    (while (and (not (eobp)) (looking-at "^[[:space:]]*$"))
      (kill-line))
    (insert (cl-loop for i from 0 below org-blank-lines-after-heading concat "\n")))

      ;; Now go to the end of content and insert lines if needed.
      (save-excursion
    (when (outline-next-heading)
      (setq next-level (nth 0 (org-heading-components)))
      ;; chomp lines back then reinsert them.
      (previous-line)
      (while (looking-at "^[[:space:]]*$")
        (kill-line)
        (previous-line))
      (unless (eobp) (end-of-line))
      (insert (cl-loop for i from 0 below (if (= current-level next-level)
                          (car org-blank-lines-after-content)
                        (cdr org-blank-lines-after-content))
               concat "\n")))))))

(defun org-format-headings (arg)
  (interactive "P")
  (save-excursion
    (org-save-outline-visibility t
      (org-cycle '(64))
      (message nil)
      (goto-char (point-min))
      (while (re-search-forward org-heading-regexp nil t)
    (org-format-heading-blank-lines)))))
  • I get an error when I add it to the hook (void-function org-end-of-meta-data). Org-mode version 8.2.10 and GNU Emacs 25.1.1. – bertfred Nov 2 '16 at 9:03
  • That is an org 8.3 function. There is probably a similarly named function in 8.2 but I don't know it off the top of my head. – John Kitchin Nov 2 '16 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.