diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index f7dab269c..0060cb9e6 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -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."