From 2d108e14a2ab0e957dadc47304157c6b0c948b19 Mon Sep 17 00:00:00 2001 From: Valentin Herrmann <50072577+vherrmann@users.noreply.github.com> Date: Wed, 30 Mar 2022 18:06:40 +0000 Subject: [PATCH] fix(org): multiple fixes for +org--insert-item There are multiple problems with the previous version of `+org--insert-item', e.g. the labels of ordered lists were not updated and it also made a difference if the point is before or after the bullet. This commit fixes this behavior, but uses a horrible hack. For the edge case of an empty item, it inserts a no-break space momentarily, so that `org-insert-item' does the right thing. --- modules/lang/org/autoload/org.el | 60 ++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/modules/lang/org/autoload/org.el b/modules/lang/org/autoload/org.el index 1e89ffc05..c563a1df0 100644 --- a/modules/lang/org/autoload/org.el +++ b/modules/lang/org/autoload/org.el @@ -30,32 +30,40 @@ (pcase (org-element-type context) ;; Add a new list item (carrying over checkboxes if necessary) ((or `item `plain-list) - (let* ((item - (if (eq 'item (org-element-type context)) - context - ;; if the context has type `plain-list', find closest item - (let ((struct (org-element-property :structure context))) - (save-excursion - (goto-char - (if (= (point) (org-element-property :begin context)) - ;; at the begin of the plain-list, we get the list and - ;; not the item with `org-element-at-point' - (1+ (car (car struct))) - (1+ (car (car (last struct)))))) - (org-element-at-point))))) - (begin (org-element-property :begin item)) - (end (org-element-property :end item)) - (cnts-begin (org-element-property :contents-begin item)) - (str (string-trim (buffer-substring begin (or cnts-begin end)) "\n+" "[ \t\r\n]+"))) - (pcase direction - (`below - (goto-char (max (1- end) (line-end-position))) - (insert "\n" str " ")) - (`above - (goto-char (line-beginning-position)) - (insert str " ") - (save-excursion (insert "\n")))))) - + (let ((orig-point (point))) + ;; Position determines where org-insert-todo-heading and `org-insert-item' + ;; insert the new list item. + (if (eq direction 'above) + (org-beginning-of-item) + (end-of-line)) + (let* ((ctx-item? (eq 'item (org-element-type context))) + (ctx-cb (org-element-property :contents-begin context)) + ;; Hack to handle edge case where the point is at the + ;; beginning of the first item + (beginning-of-list? (and (not ctx-item?) + (= ctx-cb orig-point))) + (item-context (if beginning-of-list? + (org-element-context) + context)) + ;; Horrible hack to handle edge case where the + ;; line of the bullet is empty + (ictx-cb (org-element-property :contents-begin item-context)) + (empty? (and (eq direction 'below) + ;; in case contents-begin is nil, or contents-begin + ;; equals the position end of the line, the item is + ;; empty + (or (not ictx-cb) + (= ictx-cb + (1+ (point)))))) + (pre-insert-point (point))) + ;; Insert dummy content, so that `org-insert-item' + ;; inserts content below this item + (when empty? + (insert " ")) + (org-insert-item (org-element-property :checkbox context)) + ;; Remove dummy content + (when empty? + (delete-region pre-insert-point (1+ pre-insert-point)))))) ;; Add a new table row ((or `table `table-row) (pcase direction