Browse Source

Implement Summaries for Column View in agenda.

Carsten Dominik 17 years ago
parent
commit
b0ba028394
5 changed files with 214 additions and 23 deletions
  1. 9 0
      ChangeLog
  2. 57 1
      doc/org.texi
  3. 46 13
      lisp/org-agenda.el
  4. 101 9
      lisp/org-colview.el
  5. 1 0
      lisp/org.el

+ 9 - 0
ChangeLog

@@ -1,5 +1,14 @@
 2008-04-15  Carsten Dominik  <dominik@science.uva.nl>
 2008-04-15  Carsten Dominik  <dominik@science.uva.nl>
 
 
+	* lisp/org-agenda.el (org-agenda-columns-show-summaries)
+	(org-agenda-columns-compute-summary-properties): New options.
+
+	* lisp/org-colview.el (org-agenda-colview-summarize)
+	(org-agenda-colview-compute): New functions.
+	(org-agenda-columns): Call `org-agenda-colview-summarize'.
+
+	* doc/org.texi (Agenda column view): New section.
+
 	* lisp/org.el (org-tbl-menu): Protect the use of variables that
 	* lisp/org.el (org-tbl-menu): Protect the use of variables that
 	are only available when org-table.el gets loaded.
 	are only available when org-table.el gets loaded.
 	(org-read-agenda-file-list): Error if `org-agenda-files' is a
 	(org-read-agenda-file-list): Error if `org-agenda-files' is a

+ 57 - 1
doc/org.texi

@@ -238,6 +238,7 @@ Agenda Views
 * Presentation and sorting::    How agenda items are prepared for display
 * Presentation and sorting::    How agenda items are prepared for display
 * Agenda commands::             Remote editing of Org trees
 * Agenda commands::             Remote editing of Org trees
 * Custom agenda views::         Defining special searches and views
 * Custom agenda views::         Defining special searches and views
+* Agenda column view::          Using column view for collected entries
 
 
 The built-in agenda views
 The built-in agenda views
 
 
@@ -4896,6 +4897,7 @@ window configuration is restored when the agenda exits:
 * Presentation and sorting::    How agenda items are prepared for display
 * Presentation and sorting::    How agenda items are prepared for display
 * Agenda commands::             Remote editing of Org trees
 * Agenda commands::             Remote editing of Org trees
 * Custom agenda views::         Defining special searches and views
 * Custom agenda views::         Defining special searches and views
+* Agenda column view::          Using column view for collected entries
 @end menu
 @end menu
 
 
 @node Agenda files, Agenda dispatcher, Agenda Views, Agenda Views
 @node Agenda files, Agenda dispatcher, Agenda Views, Agenda Views
@@ -5780,7 +5782,7 @@ visit org files will not be removed.
 @end table
 @end table
 
 
 
 
-@node Custom agenda views,  , Agenda commands, Agenda Views
+@node Custom agenda views, Agenda column view, Agenda commands, Agenda Views
 @section Custom agenda views
 @section Custom agenda views
 @cindex custom agenda views
 @cindex custom agenda views
 @cindex agenda views, custom
 @cindex agenda views, custom
@@ -6203,6 +6205,60 @@ foreach $line (split(/\n/,$agenda)) @{
 @end group
 @end group
 @end example
 @end example
 
 
+@node Agenda column view,  , Custom agenda views, Agenda Views
+@section Using column view in the agenda
+@cindex column view, in agenda
+@cindex agenda, column view
+
+Column view (@pxref{Column view}) is normally used to view and edit
+properties embedded in the hierarchical structure of an Org file.  It can be
+quite useful to use column view also from the agenda, where entries are
+collected by certain criteria.
+
+@table @kbd
+@kindex C-c C-x C-c
+@item C-c C-x C-c
+Turn on column view in the agenda.
+@end table
+
+To understand how to use this properly, it is important to realize that the
+entries in the agenda are no longer in their proper outline environment.
+This causes the following issues:
+
+@enumerate
+@item
+Org needs to make a decision which @code{COLUMNS} format to use.  Since the
+entries in the agenda are collected from different files, and different files
+may have different @code{COLUMNS} formats, this is a non-trivial problem.
+Org first checks if the variable @code{org-overriding-columns-format} is
+currently set, and if yes takes the format from there.  Otherwise it takes
+the format associated with the first item in the agenda, or, if that item
+does not have a specific format (defined in a property, or in it's file), it
+uses @code{org-columns-default-format}.
+@item
+If any of the columns has a summary type defined (@pxref{Column attributes}),
+turning on column view in the agenda will visit all relevant agenda files and
+make sure that the computations of this property are up to date.  This is
+also true for the special @code{CLOCKSUM} property.  Org will then sum the
+values displayed in the agenda.  In the daily/weekly agenda, the sums will
+cover a single day, in all other views they cover the entire block.  It is
+vital to realize that the agenda may show the same entry @emph{twice} (for
+example as scheduled and as a deadline), and it may show two entries from the
+same hierarchy (for example a @emph{parent} and it's @emph{child}).  In these
+cases, the summation in the agenda will lead to incorrect results because
+some values will count double.
+@item
+When the column view in the agenda shows the @code{CLOCKSUM}, that is always
+the entire clocked time for this item.  So even in the daily/weekly agenda,
+the clocksum listed in column view may originate from times outside the
+current view.  This has the advantage that you can compare these values with
+a column listing the planned total effort for a task - one of the major
+applications for column view in the agenda.  If you want information about
+clocked time in the displayed period use clock table mode (press @kbd{R} in
+the agenda).
+@end enumerate
+
+
 @node Embedded LaTeX, Exporting, Agenda Views, Top
 @node Embedded LaTeX, Exporting, Agenda Views, Top
 @chapter Embedded LaTeX
 @chapter Embedded LaTeX
 @cindex @TeX{} interpretation
 @cindex @TeX{} interpretation

+ 46 - 13
lisp/org-agenda.el

@@ -927,6 +927,28 @@ a names face, or a list like `(:background \"Red\")'."
 			(sexp :tag "face")))))
 			(sexp :tag "face")))))
 
 
 
 
+(defgroup org-agenda-column-view nil
+  "Options concerning column view in the agenda."
+  :tag "Org Agenda Column View"
+  :group 'org-agenda)
+
+(defcustom org-agenda-columns-show-summaries t
+  "Non-nil means, show summaries for columns displayed in the agenda view."
+  :group 'org-agenda-column-view
+  :type 'boolean)
+
+(defcustom org-agenda-columns-compute-summary-properties t
+  "Non-nil means, recompute all summary properties before column view.
+When column view in the agenda is listing properties that have a summary
+operator, it can go to all relevant buffers and recompute the summaries
+there.  This can mean overhead for the agenda column view, but is necessary
+to have thing up to date.
+As a special case, a CLOCKSUM property also makes sure that the clock
+computations are current."
+  :group 'org-agenda-column-view
+  :type 'boolean)
+
+
 (eval-when-compile
 (eval-when-compile
   (require 'cl))
   (require 'cl))
 (require 'org)
 (require 'org)
@@ -1858,6 +1880,7 @@ higher priority settings."
 (defvar org-agenda-multi nil)  ; dynammically scoped
 (defvar org-agenda-multi nil)  ; dynammically scoped
 (defvar org-agenda-buffer-name "*Org Agenda*")
 (defvar org-agenda-buffer-name "*Org Agenda*")
 (defvar org-pre-agenda-window-conf nil)
 (defvar org-pre-agenda-window-conf nil)
+(defvar org-agenda-columns-active nil)
 (defvar org-agenda-name nil)
 (defvar org-agenda-name nil)
 (defun org-prepare-agenda (&optional name)
 (defun org-prepare-agenda (&optional name)
   (setq org-todo-keywords-for-agenda nil)
   (setq org-todo-keywords-for-agenda nil)
@@ -1870,6 +1893,8 @@ higher priority settings."
 	  (insert "\n" (make-string (window-width) ?=) "\n"))
 	  (insert "\n" (make-string (window-width) ?=) "\n"))
 	(narrow-to-region (point) (point-max)))
 	(narrow-to-region (point) (point-max)))
     (org-agenda-reset-markers)
     (org-agenda-reset-markers)
+    (setq org-agenda-contributing-files nil)
+    (setq org-agenda-columns-active nil)
     (org-prepare-agenda-buffers (org-agenda-files))
     (org-prepare-agenda-buffers (org-agenda-files))
     (setq org-todo-keywords-for-agenda
     (setq org-todo-keywords-for-agenda
 	  (org-uniquify org-todo-keywords-for-agenda))
 	  (org-uniquify org-todo-keywords-for-agenda))
@@ -1891,7 +1916,7 @@ higher priority settings."
 	(delete-other-windows)
 	(delete-other-windows)
 	(org-switch-to-buffer-other-window abuf))))
 	(org-switch-to-buffer-other-window abuf))))
     (setq buffer-read-only nil)
     (setq buffer-read-only nil)
-    (erase-buffer)
+    (let ((inhibit-read-only t)) (erase-buffer))
     (org-agenda-mode)
     (org-agenda-mode)
     (and name (not org-agenda-name)
     (and name (not org-agenda-name)
 	 (org-set-local 'org-agenda-name name)))
 	 (org-set-local 'org-agenda-name name)))
@@ -3503,6 +3528,8 @@ Any match of REMOVE-RE will be removed from TXT."
 	   (ts (if dotime (concat (if (stringp dotime) dotime "") txt)))
 	   (ts (if dotime (concat (if (stringp dotime) dotime "") txt)))
 	   (time-of-day (and dotime (org-get-time-of-day ts)))
 	   (time-of-day (and dotime (org-get-time-of-day ts)))
 	   stamp plain s0 s1 s2 rtn srp)
 	   stamp plain s0 s1 s2 rtn srp)
+      (and (org-mode-p) buffer-file-name
+	   (add-to-list 'org-agenda-contributing-files buffer-file-name))
       (when (and dotime time-of-day org-prefix-has-time)
       (when (and dotime time-of-day org-prefix-has-time)
 	;; Extract starting and ending time and move them to prefix
 	;; Extract starting and ending time and move them to prefix
 	(when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts))
 	(when (or (setq stamp (string-match org-stamp-time-of-day-regexp ts))
@@ -3854,17 +3881,21 @@ If ERROR is non-nil, throw an error, otherwise just return nil."
 (defun org-agenda-quit ()
 (defun org-agenda-quit ()
   "Exit agenda by removing the window or the buffer."
   "Exit agenda by removing the window or the buffer."
   (interactive)
   (interactive)
-  (let ((buf (current-buffer)))
-    (if (not (one-window-p)) (delete-window))
-    (kill-buffer buf)
-    (org-agenda-reset-markers)
-    (org-columns-remove-overlays))
-  ;; Maybe restore the pre-agenda window configuration.
-  (and org-agenda-restore-windows-after-quit
-       (not (eq org-agenda-window-setup 'other-frame))
-       org-pre-agenda-window-conf
-       (set-window-configuration org-pre-agenda-window-conf)))
-
+  (if org-agenda-columns-active
+      (progn
+	(setq org-agenda-columns-active nil)
+	(org-columns-quit))
+    (let ((buf (current-buffer)))
+      (if (not (one-window-p)) (delete-window))
+      (kill-buffer buf)
+      (org-agenda-reset-markers)
+      (org-columns-remove-overlays))
+    ;; Maybe restore the pre-agenda window configuration.
+    (and org-agenda-restore-windows-after-quit
+	 (not (eq org-agenda-window-setup 'other-frame))
+	 org-pre-agenda-window-conf
+	 (set-window-configuration org-pre-agenda-window-conf))))
+  
 (defun org-agenda-exit ()
 (defun org-agenda-exit ()
   "Exit agenda by removing the window or the buffer.
   "Exit agenda by removing the window or the buffer.
 Also kill all Org-mode buffers which have been loaded by `org-agenda'.
 Also kill all Org-mode buffers which have been loaded by `org-agenda'.
@@ -3893,14 +3924,17 @@ So this is just a shortcut for `\\[org-agenda]', available in the agenda."
 When this is the global TODO list, a prefix argument will be interpreted."
 When this is the global TODO list, a prefix argument will be interpreted."
   (interactive)
   (interactive)
   (let* ((org-agenda-keep-modes t)
   (let* ((org-agenda-keep-modes t)
+	 (cols org-agenda-columns-active)
 	 (line (org-current-line))
 	 (line (org-current-line))
 	 (window-line (- line (org-current-line (window-start))))
 	 (window-line (- line (org-current-line (window-start))))
 	 (lprops (get 'org-agenda-redo-command 'org-lprops)))
 	 (lprops (get 'org-agenda-redo-command 'org-lprops)))
+    (and cols (org-columns-quit))
     (message "Rebuilding agenda buffer...")
     (message "Rebuilding agenda buffer...")
     (org-let lprops '(eval org-agenda-redo-command))
     (org-let lprops '(eval org-agenda-redo-command))
     (setq org-agenda-undo-list nil
     (setq org-agenda-undo-list nil
 	  org-agenda-pending-undo-list nil)
 	  org-agenda-pending-undo-list nil)
     (message "Rebuilding agenda buffer...done")
     (message "Rebuilding agenda buffer...done")
+    (and cols (interactive-p) (org-agenda-columns))
     (goto-line line)
     (goto-line line)
     (recenter window-line)))
     (recenter window-line)))
 
 
@@ -4965,7 +4999,6 @@ This is a command that has to be installed in `calendar-mode-map'."
     (if (fboundp 'fit-window-to-buffer)
     (if (fboundp 'fit-window-to-buffer)
 	(fit-window-to-buffer (get-buffer-window "*Dates*")))))
 	(fit-window-to-buffer (get-buffer-window "*Dates*")))))
 
 
-
 ;;; Appointment reminders
 ;;; Appointment reminders
 
 
 (defvar appt-time-msg-list)
 (defvar appt-time-msg-list)

+ 101 - 9
lisp/org-colview.el

@@ -41,13 +41,17 @@
 
 
 (defvar org-columns-current-fmt nil
 (defvar org-columns-current-fmt nil
   "Local variable, holds the currently active column format.")
   "Local variable, holds the currently active column format.")
+(make-variable-buffer-local 'org-columns-current-fmt)
 (defvar org-columns-current-fmt-compiled nil
 (defvar org-columns-current-fmt-compiled nil
   "Local variable, holds the currently active column format.
   "Local variable, holds the currently active column format.
 This is the compiled version of the format.")
 This is the compiled version of the format.")
+(make-variable-buffer-local 'org-columns-current-fmt-compiled)
 (defvar org-columns-current-widths nil
 (defvar org-columns-current-widths nil
   "Loval variable, holds the currently widths of fields.")
   "Loval variable, holds the currently widths of fields.")
+(make-variable-buffer-local 'org-columns-current-widths)
 (defvar org-columns-current-maxwidths nil
 (defvar org-columns-current-maxwidths nil
   "Loval variable, holds the currently active maximum column widths.")
   "Loval variable, holds the currently active maximum column widths.")
+(make-variable-buffer-local 'org-columns-current-maxwidths)
 (defvar org-columns-begin-marker (make-marker)
 (defvar org-columns-begin-marker (make-marker)
   "Points to the position where last a column creation command was called.")
   "Points to the position where last a column creation command was called.")
 (defvar org-columns-top-level-marker (make-marker)
 (defvar org-columns-top-level-marker (make-marker)
@@ -132,8 +136,13 @@ This is the compiled version of the format.")
 		       (and (looking-at "\\(\\**\\)\\(\\* \\)")
 		       (and (looking-at "\\(\\**\\)\\(\\* \\)")
 			    (org-get-level-face 2))))
 			    (org-get-level-face 2))))
 	 (color (list :foreground
 	 (color (list :foreground
-		      (face-attribute (or level-face 'default) :foreground)))
-	 props pom property ass width f string ov column val modval)
+		      (face-attribute
+		       (or level-face
+			   (and (eq major-mode 'org-agenda-mode)
+				(get-text-property (point-at-bol) 'face))
+			   'default) :foreground)))
+	 (face (list color 'org-column))
+	 pom property ass width f string ov column val modval)
     ;; Check if the entry is in another buffer.
     ;; Check if the entry is in another buffer.
     (unless props
     (unless props
       (if (eq major-mode 'org-agenda-mode)
       (if (eq major-mode 'org-agenda-mode)
@@ -162,9 +171,7 @@ This is the compiled version of the format.")
 	    string (format f (or modval val)))
 	    string (format f (or modval val)))
       ;; Create the overlay
       ;; Create the overlay
       (org-unmodified
       (org-unmodified
-       (setq ov (org-columns-new-overlay
-		 beg (setq beg (1+ beg)) string
-		 (list color 'org-column)))
+       (setq ov (org-columns-new-overlay beg (setq beg (1+ beg)) string face))
        (org-overlay-put ov 'keymap org-columns-map)
        (org-overlay-put ov 'keymap org-columns-map)
        (org-overlay-put ov 'org-columns-key property)
        (org-overlay-put ov 'org-columns-key property)
        (org-overlay-put ov 'org-columns-value (cdr ass))
        (org-overlay-put ov 'org-columns-value (cdr ass))
@@ -397,17 +404,22 @@ Where possible, use the standard interface for changing this line."
 (defun org-columns-edit-allowed ()
 (defun org-columns-edit-allowed ()
   "Edit the list of allowed values for the current property."
   "Edit the list of allowed values for the current property."
   (interactive)
   (interactive)
-  (let* ((key (get-char-property (point) 'org-columns-key))
+  (let* ((pom (or (get-text-property (point-at-bol) 'org-marker)
+		  (get-text-property (point-at-bol) 'org-hd-marker)
+		  (point)))
+	 (key (get-char-property (point) 'org-columns-key))
 	 (key1 (concat key "_ALL"))
 	 (key1 (concat key "_ALL"))
-	 (allowed (org-entry-get (point) key1 t))
+	 (allowed (org-entry-get pom key1 t))
 	 nval)
 	 nval)
     ;; FIXME: Cover editing TODO, TAGS etc in-buffer settings.????
     ;; FIXME: Cover editing TODO, TAGS etc in-buffer settings.????
+    ;; FIXME: Write back to #+PROPERTY setting if that is needed.
     (setq nval (read-string "Allowed: " allowed))
     (setq nval (read-string "Allowed: " allowed))
     (org-entry-put
     (org-entry-put
      (cond ((marker-position org-entry-property-inherited-from)
      (cond ((marker-position org-entry-property-inherited-from)
 	    org-entry-property-inherited-from)
 	    org-entry-property-inherited-from)
 	   ((marker-position org-columns-top-level-marker)
 	   ((marker-position org-columns-top-level-marker)
-	    org-columns-top-level-marker))
+	    org-columns-top-level-marker)
+	   (t pom))
      key1 nval)))
      key1 nval)))
 
 
 (defun org-columns-eval (form)
 (defun org-columns-eval (form)
@@ -658,6 +670,7 @@ display, or in the #+COLUMNS line of the current buffer."
 (defvar org-agenda-view-columns-initially nil
 (defvar org-agenda-view-columns-initially nil
   "When set, switch to columns view immediately after creating the agenda.")
   "When set, switch to columns view immediately after creating the agenda.")
 
 
+(defvar org-agenda-columns-show-summaries) ; defined in org-agenda.el
 (defun org-agenda-columns ()
 (defun org-agenda-columns ()
   "Turn on column view in the agenda."
   "Turn on column view in the agenda."
   (interactive)
   (interactive)
@@ -685,6 +698,7 @@ display, or in the #+COLUMNS line of the current buffer."
     (setq fmt (or fmt org-columns-default-format))
     (setq fmt (or fmt org-columns-default-format))
     (org-set-local 'org-columns-current-fmt fmt)
     (org-set-local 'org-columns-current-fmt fmt)
     (org-columns-compile-format fmt)
     (org-columns-compile-format fmt)
+    (org-agenda-colview-compute org-columns-current-fmt-compiled)
     (save-excursion
     (save-excursion
       ;; Get and cache the properties
       ;; Get and cache the properties
       (goto-char (point-min))
       (goto-char (point-min))
@@ -700,7 +714,84 @@ display, or in the #+COLUMNS line of the current buffer."
 	(mapc (lambda (x)
 	(mapc (lambda (x)
 		(goto-line (car x))
 		(goto-line (car x))
 		(org-columns-display-here (cdr x)))
 		(org-columns-display-here (cdr x)))
-	      cache)))))
+	      cache)
+	(when org-agenda-columns-show-summaries
+	  (org-agenda-colview-summarize cache))))))
+
+(defun org-agenda-colview-summarize (cache)
+  "Summarize the summarizable columns in column view in the agenda.
+This will add overlays to the date lines, to show the summary for each day."
+  (let* ((fmt (mapcar (lambda (x)
+			(list (car x) (if (equal (car x) "CLOCKSUM")
+					  'add_times (nth 4 x))))
+		      org-columns-current-fmt-compiled))
+	 line c c1 stype props lsum entries prop v)
+    (when (delq nil (mapcar 'cadr fmt))
+      ;; OK, at least one summation column, it makes sense to try this
+      (goto-char (point-max))
+      (while (not (bobp))
+	(if (not (or (get-text-property (point) 'org-date-line)
+		     (eq (get-text-property (point) 'face)
+			 'org-agenda-structure)))
+	    (beginning-of-line 0)
+	  ;; OK, this is a date line
+	  (setq line (org-current-line))
+	  (setq entries nil c cache cache nil)
+	  (while (setq c1 (pop c))
+	    (if (> (car c1) line)
+		(push c1 entries)
+	      (push c1 cache)))
+	  ;; now ENTRIES are the ones we want to use, CACHE is the rest
+	  ;; Compute the summaries for the properties we want,
+	  ;; set nil properties for the rest.
+	  (when (setq entries (mapcar 'cdr entries))
+	    (setq props
+		  (mapcar
+		   (lambda (f)
+		     (setq prop (car f) stype (nth 1 f))
+		     (cond
+		      ((equal prop "ITEM")
+		       (cons prop (buffer-substring (point-at-bol)
+						    (point-at-eol))))
+		      ((not stype) (cons prop ""))
+		      (t
+		       ;; do the summary
+		       (setq lsum 0)
+		       (mapc (lambda (x)
+			       (setq v (cdr (assoc prop x)))
+			       (if v (setq lsum (+ lsum
+						   (org-column-string-to-number
+						    v stype)))))
+			     entries)
+		       (cons prop (org-columns-number-to-string lsum stype)))))
+		   fmt))
+	    (org-columns-display-here props)
+	    (org-set-local 'org-agenda-columns-active t))
+	  (beginning-of-line 0))))))
+
+(defvar org-agenda-columns-compute-summary-properties); defined in org-agenda.el
+(defun org-agenda-colview-compute (fmt)
+  "Compute the relevant columns in the contributing source buffers."
+  (when org-agenda-columns-compute-summary-properties
+    (let ((files org-agenda-contributing-files)
+	  (org-columns-begin-marker (make-marker))
+	  (org-columns-top-level-marker (make-marker))
+	  f fm a b)
+      (while (setq f (pop files))
+	(setq b (find-buffer-visiting f))
+	(with-current-buffer (or (buffer-base-buffer b) b)
+	  (save-excursion
+	    (save-restriction
+	      (goto-char (point-min))
+	      (org-columns-get-format-and-top-level)
+	      (while (setq fm (pop fmt))
+		(if (equal (car fm) "CLOCKSUM")
+		    (org-clock-sum)
+		  (when (and (nth 4 fm)
+			     (setq a (assoc (car fm)
+					    org-columns-current-fmt-compiled))
+			     (equal (nth 4 a) (nth 4 fm)))
+		    (org-columns-compute (car fm))))))))))))
 
 
 (defun org-columns-get-autowidth-alist (s cache)
 (defun org-columns-get-autowidth-alist (s cache)
   "Derive the maximum column widths from the format and the cache."
   "Derive the maximum column widths from the format and the cache."
@@ -1056,3 +1147,4 @@ and tailing newline characters."
 (provide 'org-colview)
 (provide 'org-colview)
 
 
 ;;; org-colview.el ends here
 ;;; org-colview.el ends here
+

+ 1 - 0
lisp/org.el

@@ -1324,6 +1324,7 @@ taken from the (otherwise obsolete) variable `org-todo-interpretation'."
 (make-variable-buffer-local 'org-todo-keywords-1)
 (make-variable-buffer-local 'org-todo-keywords-1)
 (defvar org-todo-keywords-for-agenda nil)
 (defvar org-todo-keywords-for-agenda nil)
 (defvar org-done-keywords-for-agenda nil)
 (defvar org-done-keywords-for-agenda nil)
+(defvar org-agenda-contributing-files nil)
 (defvar org-not-done-keywords nil)
 (defvar org-not-done-keywords nil)
 (make-variable-buffer-local 'org-not-done-keywords)
 (make-variable-buffer-local 'org-not-done-keywords)
 (defvar org-done-keywords nil)
 (defvar org-done-keywords nil)