A better return in org-mode

| categories: emacs, orgmode | tags:

Over on Stackoverflow someone wanted a better return in org-mode. They wanted return to add items in a list (instead of M-Ret). Someone posted a partial solution, and here I improve on it to add new items to lists, new headings after a heading, and new rows to tables. In each case, a double return on an empty item, headline or table row will delete that line, and terminate the list, headlines or table. You can still use M-Ret, and this function falls through to org-return like it did before. You can use a prefix arg to get a regular return if you want one (e.g. you want to press enter on a headline to push it down).

Here is the function. Give it a try. It is a small but helpful addition I think. I have not used it for long, so if you come across issues leave a comment!

(require 'org-inlinetask)

(defun scimax/org-return (&optional ignore)
  "Add new list item, heading or table row with RET.
A double return on an empty element deletes it.
Use a prefix arg to get regular RET. "
  (interactive "P")
  (if ignore

     ((eq 'line-break (car (org-element-context)))

     ;; Open links like usual, unless point is at the end of a line.
     ;; and if at beginning of line, just press enter.
     ((or (and (eq 'link (car (org-element-context))) (not (eolp)))

     ;; It doesn't make sense to add headings in inline tasks. Thanks Anders
     ;; Johansson!

     ;; checkboxes too
      (org-insert-todo-heading nil))

     ;; lists end with two blank lines, so we need to make sure we are also not
     ;; at the beginning of a line to avoid a loop where a new entry gets
     ;; created with only one blank line.
      (if (save-excursion (beginning-of-line) (org-element-property :contents-begin (org-element-context)))
        (delete-region (line-beginning-position) (line-end-position))

     ;; org-heading
      (if (not (string= "" (org-element-property :title (org-element-context))))
          (progn (org-end-of-meta-data)
        (setf (buffer-substring
               (line-beginning-position) (line-end-position)) "")))

     ;; tables
      (if (-any?
           (lambda (x) (not (string= "" x)))
            (- (org-table-current-dline) 1)
        ;; empty row
        (setf (buffer-substring
               (line-beginning-position) (line-end-position)) "")

     ;; fall-through case

(define-key org-mode-map (kbd "RET")

Here are a few tests:

  1. numbered item
  2. second item
    1. nested number
    2. second number
  • [ ] check 1
  • [ ] check 2
  • [ ] check 3
an inline task

With some content

1 a subheading

2 another Subheading

Copyright (C) 2017 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 9.0.5

Discuss on Twitter