From 1ed9e42238bc0cc721f41dec8ab5f01a65d862d9 Mon Sep 17 00:00:00 2001 From: Ihor Radchenko Date: Wed, 27 Apr 2022 19:29:36 +0800 Subject: [PATCH] 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: "* " -> "* TODO"; After: "* " -> "* TODO"; Fixes https://orgmode.org/list/87mtg6265i.fsf@yandex.com --- lisp/org.el | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index c675fc154..1d5fc3903 100644 --- a/lisp/org.el +++ b/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))