Browse Source

Allow previous state to be shown in state change log notes.

Wanrong Lin writes:

     My TODO sequence is set up as following:

     (setq org-todo-keywords '((sequence "TODO(t)" "STARTED(s!)"
     "WAITING(w@/!)"      "MAYBE(m/!)" "DELEGATED(g@/!)"
     "DEFERRED(d!/!)" "HOLD(h!/!)" "|" "DONE(x)"      "CANCELED(c)")))

     The state change logging is great, but I wonder whether we can
     further improve it:

     1. Can we also include the original state in the log message?
     i.e.: instead of having      - State "DEFERRED"   [2009-02-11 Wed 11:38]
     we can have
     - State "DEFERRED"  from "HOLD" [2009-02-11 Wed 11:38]

     The message will be clearer, and useful even when somebody edited
     the TODO keyword in place without using the "org-todo" command
     (in that case, simply looking at all the "destination states" in
     the log message does not give us the right information).

This strikes me like a good idea, so I have implemented it with this
commit.
Carsten Dominik 16 years ago
parent
commit
c32de18ae0
3 changed files with 33 additions and 9 deletions
  1. 15 0
      lisp/ChangeLog
  2. 1 1
      lisp/org-clock.el
  3. 17 8
      lisp/org.el

+ 15 - 0
lisp/ChangeLog

@@ -1,3 +1,18 @@
+2009-02-12  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org-clock.el (org-clock-out): Add another nil for the previous
+	state into the call to `org-add-log-setup'.
+
+	* org.el (org-log-note-previous-state): New variable.
+	(org-log-note-headings): New %S escape for old state.
+	(org-todo): Call the note setup with the old state as an
+	argument.
+	(org-add-note): Add another nil for the previous state into the
+	call to `org-add-log-setup'.
+	(org-add-log-setup): New argument PREV-STATE.
+	(org-add-log-note): Handle new %S escape.
+	(org-store-log-note): Handle new %S escape.
+
 2009-02-11  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org-clock.el (org-clock-find-position): Do not swallow an item

+ 1 - 1
lisp/org-clock.el

@@ -469,7 +469,7 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
 	       (delete-char 1)))
 	(move-marker org-clock-marker nil)
 	(when org-log-note-clock-out
-	  (org-add-log-setup 'clock-out nil nil nil
+	  (org-add-log-setup 'clock-out nil nil nil nil
 			     (concat "# Task: " (org-get-heading t) "\n\n")))
 	(when org-clock-mode-line-timer
 	  (cancel-timer org-clock-mode-line-timer)

+ 17 - 8
lisp/org.el

@@ -1766,7 +1766,7 @@ When nil, only the date will be recorded."
 
 (defcustom org-log-note-headings
   '((done .  "CLOSING NOTE %t")
-    (state . "State %-12s %t")
+    (state . "State %-12s from %-12S %t")
     (note .  "Note taken on %t")
     (clock-out . ""))
   "Headings for notes added to entries.
@@ -1775,6 +1775,7 @@ context, and the cdr is the heading to be used.  The heading may also be the
 empty string.
 %t in the heading will be replaced by a time stamp.
 %s will be replaced by the new TODO state, in double quotes.
+%S will be replaced by the old TODO state, in double quotes.
 %u will be replaced by the user name.
 %U will be replaced by the full user name."
   :group  'org-todo
@@ -8573,10 +8574,10 @@ For calling through lisp, arg is also interpreted in the following way:
 	      ;; It is now done, and it was not done before
 	      (org-add-planning-info 'closed (org-current-time))
 	      (if (and (not dolog) (eq 'note org-log-done))
-		  (org-add-log-setup 'done state 'findpos 'note)))
+		  (org-add-log-setup 'done state this 'findpos 'note)))
 	    (when (and state dolog)
 	      ;; This is a non-nil state, and we need to log it
-	      (org-add-log-setup 'state state 'findpos dolog)))
+	      (org-add-log-setup 'state state this 'findpos dolog)))
 	  ;; Fixup tag positioning
 	  (org-todo-trigger-tag-changes state)
 	  (and org-auto-align-tags (not org-setting-tags) (org-set-tags nil t))
@@ -8927,7 +8928,7 @@ This function is run automatically after each state change to a DONE state."
 		;; make sure we take a note, not only a time stamp
 		(setq org-log-note-how 'note))
 	  ;; Set up for taking a record
-	  (org-add-log-setup 'state (or done-word (car org-done-keywords))
+	  (org-add-log-setup 'state (or done-word (car org-done-keywords)) this
 			     'findpos org-log-repeat)))
       (org-back-to-heading t)
       (org-add-planning-info nil nil 'closed)
@@ -9152,6 +9153,7 @@ be removed."
 (defvar org-log-note-marker (make-marker))
 (defvar org-log-note-purpose nil)
 (defvar org-log-note-state nil)
+(defvar org-log-note-previous-state nil)
 (defvar org-log-note-how nil)
 (defvar org-log-note-extra nil)
 (defvar org-log-note-window-configuration nil)
@@ -9164,10 +9166,11 @@ The auto-repeater uses this.")
   "Add a note to the current entry.
 This is done in the same way as adding a state change note."
   (interactive)
-  (org-add-log-setup 'note nil 'findpos nil))
+  (org-add-log-setup 'note nil nil 'findpos nil))
 
 (defvar org-property-end-re)
-(defun org-add-log-setup (&optional purpose state findpos how &optional extra)
+(defun org-add-log-setup (&optional purpose state prev-state
+				    findpos how &optional extra)
   "Set up the post command hook to take a note.
 If this is about to TODO state change, the new state is expected in STATE.
 When FINDPOS is non-nil, find the correct position for the note in
@@ -9200,6 +9203,7 @@ EXTRA is additional text that will be inserted into the notes buffer."
       (move-marker org-log-note-marker (point))
       (setq org-log-note-purpose purpose
 	    org-log-note-state state
+	    org-log-note-previous-state prev-state
 	    org-log-note-how how
 	    org-log-note-extra extra)
       (add-hook 'post-command-hook 'org-add-log-note 'append))))
@@ -9231,7 +9235,9 @@ EXTRA is additional text that will be inserted into the notes buffer."
 		     ((eq org-log-note-purpose 'clock-out) "stopped clock")
 		     ((eq org-log-note-purpose 'done)  "closed todo item")
 		     ((eq org-log-note-purpose 'state)
-		      (format "state change to \"%s\"" org-log-note-state))
+		      (format "state change from \"%s\" to \"%s\""
+			      (or org-log-note-previous-state "")
+			      (or org-log-note-state "")))
 		     ((eq org-log-note-purpose 'note)
 		      "this entry")
 		     (t (error "This should not happen")))))
@@ -9261,7 +9267,10 @@ EXTRA is additional text that will be inserted into the notes buffer."
 			       (current-time)))
 		   (cons "%s" (if org-log-note-state
 				  (concat "\"" org-log-note-state "\"")
-				"")))))
+				""))
+		   (cons "%S" (if org-log-note-previous-state
+				  (concat "\"" org-log-note-previous-state "\"")
+				"\"\"")))))
       (if lines (setq note (concat note " \\\\")))
       (push note lines))
     (when (or current-prefix-arg org-note-abort) (setq lines nil))