diff --git a/config.el b/config.el index e2916aa..fc17ff1 100644 --- a/config.el +++ b/config.el @@ -111,20 +111,37 @@ ;; Based off https://github.com/alphapapa/unpackaged.el#ensure-blank-lines-between-headings-and-before-contents ;;;###autoload (defun org-format (&optional prefix) - "Ensure blank lines exist after each org entry (before each heading). -With PREFIX, operate on whole buffer" + "Ensure that blank lines exist between headings and between headings and their contents. +With prefix, operate on whole buffer. Ensures that blank lines +exist after each headings's drawers." (interactive "P") - (org-map-entries - (lambda () - (let ((end (org-entry-end-position))) - (goto-char end) - (unless (string-equal (string (char-before)) "\n") - ;; Insert blank line after entry end - (insert "\n")))) - t - (if prefix - nil - 'tree))) + (org-map-entries (lambda () + (org-with-wide-buffer + ;; `org-map-entries' narrows the buffer, which prevents us from seeing + ;; newlines before the current heading, so we do this part widened. + (while (not (looking-back "\n\n" nil)) + ;; Insert blank lines before heading. + (insert "\n"))) + (let ((end (org-entry-end-position))) + ;; Insert blank lines before entry content + (forward-line) + (while (and (org-at-planning-p) + (< (point) (point-max))) + ;; Skip planning lines + (forward-line)) + (while (re-search-forward org-drawer-regexp end t) + ;; Skip drawers. You might think that `org-at-drawer-p' would suffice, but + ;; for some reason it doesn't work correctly when operating on hidden text. + ;; This works, taken from `org-agenda-get-some-entry-text'. + (re-search-forward "^[ \t]*:END:.*\n?" end t) + (goto-char (match-end 0))) + (unless (or (= (point) (point-max)) + (org-at-heading-p) + (looking-at-p "\n")) + (insert "\n")))) + t (if prefix + nil + 'tree))) ;; For elisp-autofmt ;; Local variables: