Browse Source

org-list: Do not move point and change space when promoting/demoting items

* lisp/org-list.el (org-list-struct-apply-struct): Make sure the
origin marker is not moved to bol when promoting/demoting item in
special case:
 - item
 - <point> ::
Do not remove the trailing space after point as well.
(org-insert-item): Do not expect point to remain at bol after writing
list struct.

* testing/lisp/test-org-list.el (test-org-list/indent-item): Add tests.

Fixes https://orgmode.org/list/87o88hlkvv.fsf@gmail.com
Ihor Radchenko 3 years ago
parent
commit
ed6f8dc67f
2 changed files with 29 additions and 2 deletions
  1. 14 1
      lisp/org-list.el
  2. 15 1
      testing/lisp/test-org-list.el

+ 14 - 1
lisp/org-list.el

@@ -1940,7 +1940,19 @@ Initial position of cursor is restored after the changes."
 	      (looking-at org-list-full-item-re)
 	      ;; a.  Replace bullet
 	      (unless (equal old-bul new-bul)
-		(replace-match new-bul nil nil nil 1))
+                (let ((keep-space ""))
+                  (save-excursion
+                    ;; If origin is inside the bullet, preserve the
+                    ;; spaces after origin.
+                    (when (<= (match-beginning 1) origin (match-end 1))
+                      (org-with-point-at origin
+                        (save-match-data
+                          (when (looking-at "[ \t]+")
+                            (setq keep-space (match-string 0))))))
+                    (replace-match "" nil nil nil 1)
+                    (goto-char (match-end 1))
+                    (insert-before-markers new-bul)
+                    (insert keep-space))))
 	      ;; b.  Replace checkbox.
 	      (cond
 	       ((equal (match-string 3) new-box))
@@ -2286,6 +2298,7 @@ item is invisible."
 	  (setq struct (org-list-insert-item pos struct prevs checkbox desc))
 	  (org-list-write-struct struct (org-list-parents-alist struct))
 	  (when checkbox (org-update-checkbox-count-maybe))
+          (beginning-of-line)
 	  (looking-at org-list-full-item-re)
 	  (goto-char (if (and (match-beginning 4)
 			      (save-match-data

+ 15 - 1
testing/lisp/test-org-list.el

@@ -298,7 +298,21 @@ b. Item 2<point>"
 	    (push-mark (point) t t)
 	    (goto-char (point-max))
 	    (let (org-list-demote-modify-bullet) (org-indent-item))
-	    (buffer-string)))))
+	    (buffer-string))))
+  ;; When point is right after empty item, do not move point.
+  (should
+   (= 13
+      (org-test-with-temp-text "
+- item
+- <point> ::"
+        (org-indent-item)
+        (point))))
+  ;; Preserve space after point upon promoting level.
+  (org-test-with-temp-text "
+- item
+- <point> 	::"
+    (org-indent-item)
+    (should (looking-at-p " \t"))))
 
 (ert-deftest test-org-list/indent-item-tree ()
   "Test `org-indent-item-tree' specifications."