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
This commit is contained in:
Ihor Radchenko 2022-04-27 19:29:36 +08:00
parent e142bd8a9a
commit 1ed9e42238
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
1 changed files with 13 additions and 8 deletions

View File

@ -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))