From mboxrd@z Thu Jan 1 00:00:00 1970 From: zyg Subject: Problem with point in state change hook function Date: Wed, 22 Aug 2012 16:31:21 +1000 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Return-path: Received: from eggs.gnu.org ([208.118.235.92]:41486) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T44TR-0001N5-7J for emacs-orgmode@gnu.org; Wed, 22 Aug 2012 02:31:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T44TL-0000Qu-2r for emacs-orgmode@gnu.org; Wed, 22 Aug 2012 02:31:29 -0400 Received: from mail-ob0-f169.google.com ([209.85.214.169]:63817) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T44TK-0000Qn-U0 for emacs-orgmode@gnu.org; Wed, 22 Aug 2012 02:31:23 -0400 Received: by obhx4 with SMTP id x4so1070516obh.0 for ; Tue, 21 Aug 2012 23:31:22 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org My brain works in two non-standard org ways: - I don't like having the =CLOSED= timestamp outside of property drawers, and - no =todo= tag (or a =todo= tag of "" if you like) is still a =todo= tag and often means =DONE=. So standard state change logging doesn't work for me. All I really want to track, though, is the timestamp of the latest state change. Hence: #+begin_src emacs-lisp (defun my/log-state-change () "logs timestamps in PROPERTIES for any todo-tag state change (LAST). " (interactive) (save-excursion (let* ((stamp (org-string-timestamp nil t t nil nil nil))) (org-set-property "LAST" (concatenate 'string org-state " " stamp))))) #+end_src #+begin_src emacs-lisp (add-hook 'org-after-todo-state-change-hook 'my/log-state-change) #+end_src This works fine except for the following conditions: - the =todo= tag is changing to a non-nil value, - there is not (yet) any heading, - point is exactly at the start of the header (after stars and =todo= tag if any), and - there is no properties drawer yet. In this case, point moves from the header to after the properties drawer. A few examples showing intention and bug (representing point by ^): Example 1: works - before shift-right #+begin_example * ^test #+end_example - after shift-right #+begin_example * TODO ^test :PROPERTIES: :OPEN: [2012-08-22 Wed 15:51] :LAST: TODO [2012-08-22 Wed 15:51] :END: #+end_example Example 2: buggy - point shifts - before shift-right #+begin_example * ^ #+end_example - after shift-right #+begin_example * TODO :PROPERTIES: :LAST: TODO [2012-08-22 Wed 15:51] :END:^ #+end_example Example 3: ok - before shift-right #+begin_example ^* #+end_example - after shift-right #+begin_example * TODO ^ :PROPERTIES: :LAST: TODO [2012-08-22 Wed 15:51] :END: #+end_example Example 4: strangely, this works (standard TODO -> DONE -> "" cycle) - before shift-right #+begin_example * DONE ^ #+end_example - after shift-right #+begin_example * ^ :PROPERTIES: :LAST: [2012-08-22 Wed 15:51] :END: #+end_example Any ideas? How can point change if you have a save-excursion in place? My main thought was that the properties drawer is being inserted before point but /only when/ there is no heading. I've spent some time squinting at org-entry-put to check this, but debugging let alone understanding org-with-point-at is way beyond me.