Revise +org--insert-item

Which powers +org/insert-item-below and +org/insert-item-above.
This commit is contained in:
Henrik Lissner 2020-07-26 15:42:50 -04:00
parent e6979166ee
commit 076cee4e89
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395

View file

@ -23,68 +23,56 @@
t)))
(defun +org--insert-item (direction)
(let* ((context
(save-excursion
(when (bolp)
(back-to-indentation)
(forward-char))
(org-element-lineage
(org-element-context)
'(table table-row headline inlinetask item plain-list)
t)))
(type (org-element-type context)))
(cond ((memq type '(item plain-list))
(let ((marker (org-element-property :bullet context))
(pad (save-excursion
(org-beginning-of-item)
(back-to-indentation)
(- (point) (line-beginning-position)))))
(save-match-data
(pcase direction
(`below
(org-end-of-item)
(backward-char)
(end-of-line)
(if (and marker (string-match "\\([0-9]+\\)\\([).] *\\)" marker))
(let ((l (line-number-at-pos)))
(org-insert-item)
(when (= l (line-number-at-pos))
(org-next-item)
(org-end-of-line)))
(insert "\n" (make-string pad 32) (or marker ""))))
(`above
(org-beginning-of-item)
(if (and marker (string-match-p "[0-9]+[).]" marker))
(org-insert-item)
(insert (make-string pad 32) (or marker ""))
(save-excursion (insert "\n")))))))
(when (org-element-property :checkbox context)
(insert "[ ] ")))
(let ((context (org-element-lineage
(org-element-context)
'(table table-row headline inlinetask item plain-list)
t)))
(pcase (org-element-type context)
;; Add a new list item (carrying over checkboxes if necessary)
((or `item `plain-list)
;; Position determines where org-insert-todo-heading and org-insert-item
;; insert the new list item.
(if (eq direction 'above)
(org-beginning-of-item)
(org-end-of-item))
(if (org-element-property :checkbox context)
(org-insert-todo-heading nil)
(org-insert-item)))
((memq type '(table table-row))
(pcase direction
('below (save-excursion (org-table-insert-row t))
(org-table-next-row))
('above (save-excursion (org-shiftmetadown))
(+org/table-previous-row))))
;; Add a new table row
((or `table `table-row)
(pcase direction
('below (save-excursion (org-table-insert-row t))
(org-table-next-row))
('above (save-excursion (org-shiftmetadown))
(+org/table-previous-row))))
((let ((level (or (org-current-level) 1)))
(pcase direction
(`below
(let (org-insert-heading-respect-content)
(goto-char (line-end-position))
(org-end-of-subtree)
(insert "\n" (make-string level ?*) " ")))
(`above
(org-back-to-heading)
(insert (make-string level ?*) " ")
(save-excursion (insert "\n"))))
(when-let* ((todo-keyword (org-element-property :todo-keyword context))
(todo-type (org-element-property :todo-type context)))
(org-todo (cond ((eq todo-type 'done)
(car (+org-get-todo-keywords-for todo-keyword)))
(todo-keyword)
('todo)))))))
;; Otherwise, add a new heading, carrying over any todo state, if
;; necessary.
(_
(let ((level (or (org-current-level) 1)))
;; I intentionally avoid `org-insert-heading' and the like because they
;; impose unpredictable whitespace rules depending on the cursor
;; position. It's simpler to express this command's responsibility at a
;; lower level than work around all the quirks in org's API.
(pcase direction
(`below
(let (org-insert-heading-respect-content)
(goto-char (line-end-position))
(org-end-of-subtree)
(insert "\n" (make-string level ?*) " ")))
(`above
(org-back-to-heading)
(insert (make-string level ?*) " ")
(save-excursion (insert "\n"))))
(when-let* ((todo-keyword (org-element-property :todo-keyword context))
(todo-type (org-element-property :todo-type context)))
(org-todo
(cond ((eq todo-type 'done)
;; Doesn't make sense to create more "DONE" headings
(car (+org-get-todo-keywords-for todo-keyword)))
(todo-keyword)
('todo)))))))
(when (org-invisible-p)
(org-show-hidden-entry))
@ -278,9 +266,9 @@ If on a:
(org-element-property :end context)))))))
;; I use this instead of `org-insert-item' or `org-insert-heading' which are too
;; opinionated and perform this simple task incorrectly (e.g. whitespace in the
;; wrong places).
;; I use these instead of `org-insert-item' or `org-insert-heading' because they
;; impose bizarre whitespace rules depending on cursor location and many
;; settings. These commands have a much simpler responsibility.
;;;###autoload
(defun +org/insert-item-below (count)
"Inserts a new heading, table cell or item below the current one."