瀏覽代碼

New function to take a note, just like state changes do, but now on demand.

This function is on `C-c C-z' in an org-mode buffer, and
also on `z' in the agenda.

Also some other small fixes.
Carsten Dominik 17 年之前
父節點
當前提交
2b3fe71634
共有 3 個文件被更改,包括 65 次插入15 次删除
  1. 13 0
      ChangeLog
  2. 29 5
      lisp/org-agenda.el
  3. 23 10
      lisp/org.el

+ 13 - 0
ChangeLog

@@ -1,3 +1,16 @@
+2008-03-28  Carsten Dominik  <dominik@science.uva.nl>
+
+	* lisp/org-agenda.el (org-agenda-deadline-leaders): Allow a
+	function value for the deadline leader.
+	(org-agenda-get-deadlines): Deal with new function value.
+
+	* lisp/org.el (org-update-checkbox-count): Fix bug with checkbox
+	counting.
+	(org-add-note): New command.
+	(org-add-log-setup): Renamed from `org-add-log-maybe'.
+	(org-log-note-headings): New entry for plain notes (i.e. notes not
+	related to state changes or clocking).
+
 2008-03-27  Carsten Dominik  <dominik@science.uva.nl>
 2008-03-27  Carsten Dominik  <dominik@science.uva.nl>
 
 
 	* org-agenda.el: New file, split out from org.el.
 	* org-agenda.el: New file, split out from org.el.

+ 29 - 5
lisp/org-agenda.el

@@ -33,8 +33,6 @@
 
 
 (require 'org)
 (require 'org)
 (eval-when-compile
 (eval-when-compile
-;  (require 'cl)
-;  (require 'gnus-sum)
   (require 'calendar))
   (require 'calendar))
 
 
 (declare-function add-to-diary-list "diary-lib"
 (declare-function add-to-diary-list "diary-lib"
@@ -823,7 +821,9 @@ is (was)."
   :group 'org-agenda-line-format
   :group 'org-agenda-line-format
   :type '(list
   :type '(list
 	  (string :tag "Deadline today   ")
 	  (string :tag "Deadline today   ")
-	  (string :tag "Deadline relative")))
+	  (choice :tag "Deadline relative"
+		  (string :tag "Format string")
+		  (function))))
 
 
 (defcustom org-agenda-remove-times-when-in-prefix t
 (defcustom org-agenda-remove-times-when-in-prefix t
   "Non-nil means, remove duplicate time specifications in agenda items.
   "Non-nil means, remove duplicate time specifications in agenda items.
@@ -1001,6 +1001,8 @@ The following commands are available:
 (org-defkey org-agenda-mode-map "w"        'org-agenda-week-view)
 (org-defkey org-agenda-mode-map "w"        'org-agenda-week-view)
 (org-defkey org-agenda-mode-map "m"        'org-agenda-month-view)
 (org-defkey org-agenda-mode-map "m"        'org-agenda-month-view)
 (org-defkey org-agenda-mode-map "y"        'org-agenda-year-view)
 (org-defkey org-agenda-mode-map "y"        'org-agenda-year-view)
+(org-defkey org-agenda-mode-map "\C-c\C-z" 'org-agenda-add-note)
+(org-defkey org-agenda-mode-map "z"        'org-agenda-add-note)
 (org-defkey org-agenda-mode-map [(shift right)] 'org-agenda-date-later)
 (org-defkey org-agenda-mode-map [(shift right)] 'org-agenda-date-later)
 (org-defkey org-agenda-mode-map [(shift left)] 'org-agenda-date-earlier)
 (org-defkey org-agenda-mode-map [(shift left)] 'org-agenda-date-earlier)
 (org-defkey org-agenda-mode-map [?\C-c ?\C-x (right)] 'org-agenda-date-later)
 (org-defkey org-agenda-mode-map [?\C-c ?\C-x (right)] 'org-agenda-date-later)
@@ -1086,6 +1088,7 @@ The following commands are available:
     ["Cycle TODO" org-agenda-todo t]
     ["Cycle TODO" org-agenda-todo t]
     ["Archive subtree" org-agenda-archive t]
     ["Archive subtree" org-agenda-archive t]
     ["Delete subtree" org-agenda-kill t]
     ["Delete subtree" org-agenda-kill t]
+    ["Add note" org-agenda-add-note t]
     "--"
     "--"
     ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)]
     ["Goto Today" org-agenda-goto-today (org-agenda-check-type nil 'agenda 'timeline)]
     ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
     ["Next Dates" org-agenda-later (org-agenda-check-type nil 'agenda)]
@@ -3239,8 +3242,10 @@ the documentation of `org-diary'."
 		      (setq txt (org-format-agenda-item
 		      (setq txt (org-format-agenda-item
 				 (if (= diff 0)
 				 (if (= diff 0)
 				     (car org-agenda-deadline-leaders)
 				     (car org-agenda-deadline-leaders)
-				   (format (nth 1 org-agenda-deadline-leaders)
-					   diff))
+				   (if (functionp (nth 1 org-agenda-deadline-leaders))
+				       (funcall (nth 1 org-agenda-deadline-leaders) diff date)
+				     (format (nth 1 org-agenda-deadline-leaders)
+					     diff)))
 				 head category tags timestr))))
 				 head category tags timestr))))
 		(setq txt org-agenda-no-heading-message))
 		(setq txt org-agenda-no-heading-message))
 	      (when txt
 	      (when txt
@@ -4395,6 +4400,25 @@ the same tree node, and the headline of the tree node in the Org-mode file."
 	(org-agenda-change-all-lines newhead hdmarker 'fixface))
 	(org-agenda-change-all-lines newhead hdmarker 'fixface))
       (move-to-column col))))
       (move-to-column col))))
 
 
+(defun org-agenda-add-note (&optional arg)
+  "Add a time-stamped note to the entry at point."
+  (interactive "P")
+  (org-agenda-check-no-diary)
+  (let* ((marker (or (get-text-property (point) 'org-marker)
+		     (org-agenda-error)))
+	 (buffer (marker-buffer marker))
+	 (pos (marker-position marker))
+	 (hdmarker (get-text-property (point) 'org-hd-marker))
+	 (inhibit-read-only t))
+    (with-current-buffer buffer
+      (widen)
+      (goto-char pos)
+      (org-show-context 'agenda)
+      (save-excursion
+	(and (outline-next-heading)
+	     (org-flag-heading nil)))   ; show the next heading
+      (org-add-note))))
+
 (defun org-agenda-change-all-lines (newhead hdmarker &optional fixface)
 (defun org-agenda-change-all-lines (newhead hdmarker &optional fixface)
   "Change all lines in the agenda buffer which match HDMARKER.
   "Change all lines in the agenda buffer which match HDMARKER.
 The new content of the line will be NEWHEAD (as modified by
 The new content of the line will be NEWHEAD (as modified by

+ 23 - 10
lisp/org.el

@@ -1530,10 +1530,11 @@ When nil, only the date will be recorded."
   :type 'boolean)
   :type 'boolean)
 
 
 (defcustom org-log-note-headings
 (defcustom org-log-note-headings
-  '((done . "CLOSING NOTE %t")
+  '((done .  "CLOSING NOTE %t")
     (state . "State %-12s %t")
     (state . "State %-12s %t")
+    (note .  "Note taken on %t")
     (clock-out . ""))
     (clock-out . ""))
-  "Headings for notes added when clocking out or closing TODO items.
+  "Headings for notes added to entries.
 The value is an alist, with the car being a symbol indicating the note
 The value is an alist, with the car being a symbol indicating the note
 context, and the cdr is the heading to be used.  The heading may also be the
 context, and the cdr is the heading to be used.  The heading may also be the
 empty string.
 empty string.
@@ -1548,8 +1549,12 @@ empty string.
 	  (cons (const :tag
 	  (cons (const :tag
 		       "Heading when changing todo state (todo sequence only)"
 		       "Heading when changing todo state (todo sequence only)"
 		       state) string)
 		       state) string)
+	  (cons (const :tag "Heading when just taking a note" note) string)
 	  (cons (const :tag "Heading when clocking out" clock-out) string)))
 	  (cons (const :tag "Heading when clocking out" clock-out) string)))
 
 
+(unless (assq 'note org-log-note-headings)
+  (push '(note . "%t") org-log-note-headings))
+
 (defcustom org-log-states-order-reversed t
 (defcustom org-log-states-order-reversed t
   "Non-nil means, the latest state change note will be directly after heading.
   "Non-nil means, the latest state change note will be directly after heading.
 When nil, the notes will be orderer according to time."
 When nil, the notes will be orderer according to time."
@@ -5552,7 +5557,7 @@ the whole buffer."
                (org-beginning-of-item)
                (org-beginning-of-item)
                (setq curr-ind (org-get-indentation))
                (setq curr-ind (org-get-indentation))
                (setq next-ind curr-ind)
                (setq next-ind curr-ind)
-               (while (= curr-ind next-ind)
+               (while (and (org-at-item-p) (= curr-ind next-ind))
                  (save-excursion (end-of-line) (setq eline (point)))
                  (save-excursion (end-of-line) (setq eline (point)))
                  (if (re-search-forward re-box eline t)
                  (if (re-search-forward re-box eline t)
 		     (if (member (match-string 2) '("[ ]" "[-]"))
 		     (if (member (match-string 2) '("[ ]" "[-]"))
@@ -8490,10 +8495,10 @@ For calling through lisp, arg is also interpreted in the following way:
 	    ;; It is now done, and it was not done before
 	    ;; It is now done, and it was not done before
 	    (org-add-planning-info 'closed (org-current-time))
 	    (org-add-planning-info 'closed (org-current-time))
 	    (if (and (not dolog) (eq 'note org-log-done))
 	    (if (and (not dolog) (eq 'note org-log-done))
-		(org-add-log-maybe 'done state 'findpos 'note)))
+		(org-add-log-setup 'done state 'findpos 'note)))
 	  (when (and state dolog)
 	  (when (and state dolog)
 	    ;; This is a non-nil state, and we need to log it
 	    ;; This is a non-nil state, and we need to log it
-	    (org-add-log-maybe 'state state 'findpos dolog)))
+	    (org-add-log-setup 'state state 'findpos dolog)))
 	;; Fixup tag positioning
 	;; Fixup tag positioning
 	(and org-auto-align-tags (not org-setting-tags) (org-set-tags nil t))
 	(and org-auto-align-tags (not org-setting-tags) (org-set-tags nil t))
 	(run-hooks 'org-after-todo-state-change-hook)
 	(run-hooks 'org-after-todo-state-change-hook)
@@ -8674,7 +8679,7 @@ This function is run automatically after each state change to a DONE state."
 				(default-value 'post-command-hook)))
 				(default-value 'post-command-hook)))
 		     (eq org-log-note-purpose 'done)))
 		     (eq org-log-note-purpose 'done)))
 	;; Make sure a note is taken;
 	;; Make sure a note is taken;
-	(org-add-log-maybe 'state (or done-word (car org-done-keywords))
+	(org-add-log-setup 'state (or done-word (car org-done-keywords))
 			   'findpos org-log-repeat))
 			   'findpos org-log-repeat))
       (org-back-to-heading t)
       (org-back-to-heading t)
       (org-add-planning-info nil nil 'closed)
       (org-add-planning-info nil nil 'closed)
@@ -8875,7 +8880,13 @@ be removed."
   "Message to be displayed after a log note has been stored.
   "Message to be displayed after a log note has been stored.
 The auto-repeater uses this.")
 The auto-repeater uses this.")
 
 
-(defun org-add-log-maybe (&optional purpose state findpos how)
+(defun org-add-note ()
+  "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 t nil))
+
+(defun org-add-log-setup (&optional purpose state findpos how)
   "Set up the post command hook to take a note.
   "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.
 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
 When FINDPOS is non-nil, find the correct position for the note in
@@ -8925,7 +8936,9 @@ the current entry.  If not, assume that it can be inserted at point."
 		     ((eq org-log-note-purpose 'done)  "closed todo item")
 		     ((eq org-log-note-purpose 'done)  "closed todo item")
 		     ((eq org-log-note-purpose 'state)
 		     ((eq org-log-note-purpose 'state)
 		      (format "state change to \"%s\"" org-log-note-state))
 		      (format "state change to \"%s\"" org-log-note-state))
-		   (t (error "This should not happen")))))
+		     ((eq org-log-note-purpose 'note)
+		      "this entry")
+		     (t (error "This should not happen")))))
     (org-set-local 'org-finish-function 'org-store-log-note)))
     (org-set-local 'org-finish-function 'org-store-log-note)))
 
 
 (defvar org-note-abort nil) ; dynamically scoped
 (defvar org-note-abort nil) ; dynamically scoped
@@ -12702,7 +12715,7 @@ If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
       (insert " => " (format "%2d:%02d" h m))
       (insert " => " (format "%2d:%02d" h m))
       (move-marker org-clock-marker nil)
       (move-marker org-clock-marker nil)
       (when org-log-note-clock-out
       (when org-log-note-clock-out
-	(org-add-log-maybe 'clock-out))
+	(org-add-log-setup 'clock-out))
       (when org-mode-line-timer
       (when org-mode-line-timer
 	(cancel-timer org-mode-line-timer)
 	(cancel-timer org-mode-line-timer)
 	(setq org-mode-line-timer nil))
 	(setq org-mode-line-timer nil))
@@ -13811,7 +13824,7 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]."
 (org-defkey org-mode-map "\C-c\C-o" 'org-open-at-point)
 (org-defkey org-mode-map "\C-c\C-o" 'org-open-at-point)
 (org-defkey org-mode-map "\C-c%"    'org-mark-ring-push)
 (org-defkey org-mode-map "\C-c%"    'org-mark-ring-push)
 (org-defkey org-mode-map "\C-c&"    'org-mark-ring-goto)
 (org-defkey org-mode-map "\C-c&"    'org-mark-ring-goto)
-(org-defkey org-mode-map "\C-c\C-z" 'org-time-stamp)  ; Alternative binding
+(org-defkey org-mode-map "\C-c\C-z" 'org-add-note)  ; Alternative binding
 (org-defkey org-mode-map "\C-c."    'org-time-stamp)  ; Minor-mode reserved
 (org-defkey org-mode-map "\C-c."    'org-time-stamp)  ; Minor-mode reserved
 (org-defkey org-mode-map "\C-c!"    'org-time-stamp-inactive) ; Minor-mode r.
 (org-defkey org-mode-map "\C-c!"    'org-time-stamp-inactive) ; Minor-mode r.
 (org-defkey org-mode-map "\C-c,"    'org-priority)    ; Minor-mode reserved
 (org-defkey org-mode-map "\C-c,"    'org-priority)    ; Minor-mode reserved