11

Like many of us, I use org-mode for two different things:

  1. As a TODO list manager
  2. As a text outliner

I'd like my blank lines to work differently based on context.

  1. TODO list: no blank lines
  2. text outline: automatically insert 1 blank line when non-heading text precedes a heading

In other words, when I'm doing a TODO list when I have many headings in a row, I don't want stray line breaks between them.

TODO list mode, no line breaks:

* Organize Party [33%]
 ** TODO Call people [1/2]
 *** TODO Peter
 *** DONE Sarah
 ** TODO Buy food
 ** DONE Talk to neighbor 

However, when I'm writing text, I want line breaks for the sake of visual whitespace / ease of reading.

outline mode, blank line before heading:

* Heading 
This is a document that has a heading, and a body. The body will consist of two paragraphs with sub-headings.

* Body  
This is an introduction to the body. The body has two sub-headings, each of which have their own paragraph.  

** The First Paragraph  
This is the first of two paragraphs. 

** The Second Paragraph
This is the second of two paragraphs.  

I've already set org-blank-before-new-entry to auto:

 ((heading . auto)
 (plain-list-item . auto))

But I think org-blank-before-new-entry works by detecting other blank lines in the area. I want it to detect whether the preceding line of text is a heading or a non-heading.

How can I modify org-blank-before-new-entry so that when I'm in a TODO list consisting only of headings, org-meta-return doesn't add a line break? but after a block of text, it does?

incandescentman
  • 4,111
  • 16
  • 53
  • Have you found a fix for this? I tried asking the same question on [the emacs subreddit](https://www.reddit.com/r/emacs/comments/3jlor8/hack_request_orgmode_heading_and_blank_lines/) a while back but to no avail. – MajorBriggs Oct 14 '15 at 09:32
  • Yes, through a custom function. I will post. – incandescentman Oct 16 '15 at 03:26

1 Answers1

8

This can be done by creating a custom function that checks to see whether it's on an org-heading.

(setq org-blank-before-new-entry
      '((heading . always)
       (plain-list-item . nil)))

(defun call-rebinding-org-blank-behaviour (fn)
  (let ((org-blank-before-new-entry
         (copy-tree org-blank-before-new-entry)))
    (when (org-at-heading-p)
      (rplacd (assoc 'heading org-blank-before-new-entry) nil))
    (call-interactively fn)))

(defun smart-org-meta-return-dwim ()
  (interactive)
  (call-rebinding-org-blank-behaviour 'org-meta-return))

(defun smart-org-insert-todo-heading-dwim ()
  (interactive)
  (call-rebinding-org-blank-behaviour 'org-insert-todo-heading))

(define-key org-mode-map (kbd "M-<return>") 'smart-org-meta-return-dwim) 
incandescentman
  • 4,111
  • 16
  • 53
  • 1
    How could I get this working for the three other ways to insert headings, as well: `C-ret` (org-insert-heading-respect-content), `M-S-return` (org-insert-todo-heading) and `C-S-return` (org-insert-todo-heading-respect-content)? – MajorBriggs Oct 22 '15 at 11:35
  • To clarify: `org-insert-todo-heading` doesn't work even if I bind it to a key like this: (define-key org-mode-map (kbd "M-S-") 'smart-org-insert-todo-heading-dwim) – MajorBriggs Oct 22 '15 at 12:34