Browse Source

org-todo: Fix point moving after setting todo keyword in empty heading

* lisp/org.el (org-todo): Insert new todo keyword before
`save-excursion' markers.  This avoids apparent point movement when a
new keyword is inserted into an empty heading.
Before: "* <point>" -> "*<point> TODO";
After: "* <point>" -> "* TODO<point>";

Fixes https://orgmode.org/list/87mtg6265i.fsf@yandex.com
Ihor Radchenko 3 năm trước cách đây
mục cha
commit
1ed9e42238
1 tập tin đã thay đổi với 13 bổ sung8 xóa
  1. 13 8
      lisp/org.el

+ 13 - 8
lisp/org.el

@@ -8976,14 +8976,19 @@ When called through ELisp, arg is also interpreted in the following way:
 		    (throw 'exit nil)))))
 	    (store-match-data match-data)
             (org-fold-core-ignore-modifications
-                (save-excursion
-                  (goto-char (match-beginning 0))
-                  (setf (buffer-substring (match-beginning 0) (match-end 0)) "")
-                  (insert-and-inherit next)
-                  (unless (org-invisible-p (line-beginning-position))
-                    (org-fold-region (line-beginning-position)
-                                  (line-end-position)
-                                  nil))))
+                (goto-char (match-beginning 0))
+              (replace-match "")
+              ;; We need to use `insert-before-markers-and-inherit'
+              ;; because: (1) We want to preserve the folding state
+              ;; text properties; (2) We do not want to make point
+              ;; move before new todo state when inserting a new todo
+              ;; into an empty heading.  In (2), the above
+              ;; `save-excursion' is relying on markers saved before.
+              (insert-before-markers-and-inherit next)
+              (unless (org-invisible-p (line-beginning-position))
+                (org-fold-region (line-beginning-position)
+                              (line-end-position)
+                              nil)))
 	    (cond ((and org-state (equal this org-state))
 		   (message "TODO state was already %s" (org-trim next)))
 		  ((not (pos-visible-in-window-p hl-pos))