Browse Source

Add clock persistence.

Clock-related data are saved when exiting emacs ands restored when emacs
is restarted. The data saved include the contents of `org-clock-history',
and the running clock, if there is one.

To use this, you will need to add

(require 'org-clock)
(org-clock-persistence-insinuate)

to your .emacs and either add

(setq org-clock-persist t)
(setq org-clock-in-resume t)

or set those options to t in custom.

This patch requires the clock resume patch.

Add missing blank line to changelog
James TD Smith 16 years ago
parent
commit
6ca2053982
2 changed files with 109 additions and 0 deletions
  1. 17 0
      lisp/ChangeLog
  2. 92 0
      lisp/org-clock.el

+ 17 - 0
lisp/ChangeLog

@@ -31,6 +31,22 @@
 	(org-clock-in): When clocking in to an entry, if
 	(org-clock-in): When clocking in to an entry, if
 	`org-clock-in-resume' is set, check if the first clock line is
 	`org-clock-in-resume' is set, check if the first clock line is
 	open and if so, start the clock from the time in the clock line.
 	open and if so, start the clock from the time in the clock line.
+	(org-clock-persist): Add a custom option to toggle clock
+	persistence.
+	(org-clock-persist-query-save): Add a custom option to toggle
+	asking the user if they want to save the running clock when
+	exiting.
+	(org-clock-persist-query-resume): Add a custom option to toggle
+	asking the user if they want to resume the saved clock when Emacs
+	is restarted.
+	(org-clock-save): Add a function to save clock data.
+	This includes the contents of `org-clock-history' and the buffer
+	and position of the currently clocked task, if any.
+	(org-clock-load): Add a function to load clock data.
+	This populates `org-clock-history', and resumes the saved clocked
+	task if there is one.
+	(org-clock-persistence-insinuate): Add a method to set up the
+	hooks for clock persistence.
 
 
 2008-10-22  Carsten Dominik  <dominik@science.uva.nl>
 2008-10-22  Carsten Dominik  <dominik@science.uva.nl>
 
 
@@ -317,6 +333,7 @@
 	* org-export-latex.el (org-export-latex-keywords-maybe): Bug fix.
 	* org-export-latex.el (org-export-latex-keywords-maybe): Bug fix.
 
 
 2008-09-22  James TD Smith  <ahktenzero@mohorovi.cc>
 2008-09-22  James TD Smith  <ahktenzero@mohorovi.cc>
+
 	* org-plot.el (org-plot/gnuplot): Make tables starting with a
 	* org-plot.el (org-plot/gnuplot): Make tables starting with a
 	hline work correctly.
 	hline work correctly.
 	(org-plot/gnuplot-script): Put commas at the end of each script
 	(org-plot/gnuplot-script): Put commas at the end of each script

+ 92 - 0
lisp/org-clock.el

@@ -101,6 +101,28 @@ has not been closed, resume the clock from that point"
   :group 'org-clock
   :group 'org-clock
   :type 'boolean)
   :type 'boolean)
 
 
+(defcustom org-clock-persist nil
+  "When non-nil, save the running clock when emacs is closed, and
+  resume it next time emacs is started."
+  :group 'org-clock
+  :type 'boolean)
+
+(defcustom org-clock-persist-file "~/.emacs.d/org-clock-save.el"
+  "File to save clock data to"
+  :group 'org-clock
+  :type 'string)
+
+(defcustom org-clock-persist-query-save nil
+  "When non-nil, ask before saving the current clock on exit"
+  :group 'org-clock
+  :type 'boolean)
+
+(defcustom org-clock-persist-query-resume t
+  "When non-nil, ask before resuming any stored clock during
+load."
+  :group 'org-clock
+  :type 'boolean)
+
 ;;; The clock for measuring work time.
 ;;; The clock for measuring work time.
 
 
 (defvar org-mode-line-string "")
 (defvar org-mode-line-string "")
@@ -989,6 +1011,76 @@ the currently selected interval size."
 			   lines)
 			   lines)
 		   "\n"))))
 		   "\n"))))
 
 
+(defun org-clock-save ()
+  "Persist various clock-related data to disk"
+  (with-current-buffer (find-file (expand-file-name org-clock-persist-file))
+    (progn (delete-region (point-min) (point-max))
+	   ;;Store clock
+	   (insert (format ";; org-persist.el - %s at %s\n" system-name (time-stamp-string)))
+	   (if (and org-clock-persist (marker-buffer org-clock-marker)
+		    (or (not org-clock-persist-query-save)
+			(y-or-n-p (concat "Save current clock ("
+					  (substring-no-properties org-clock-heading)
+					  ")"))))
+	       (insert "(setq resume-clock '(\""
+		       (buffer-file-name (marker-buffer org-clock-marker))
+		       "\" . " (int-to-string (marker-position org-clock-marker))
+		       "))\n"))
+	   ;;Store clocked task history. Tasks are stored reversed to make
+	   ;;reading simpler
+	   (if org-clock-history
+	       (insert "(setq stored-clock-history '("
+		       (mapconcat
+			(lambda (m)
+			  (when (marker-buffer m)
+			    (concat "(\"" (buffer-file-name (marker-buffer m))
+				    "\" . " (int-to-string (marker-position m))
+				")")))
+			(reverse org-clock-history) " ") "))\n"))
+	   (save-buffer)
+	   (kill-buffer (current-buffer)))))
+
+(defvar org-clock-loaded nil)
+
+(require 'timestamp)
+
+(defun org-clock-load ()
+  "Load various clock-related data from disk, optionally resuming
+a stored clock"
+  (if (not org-clock-loaded)
+      (let ((filename (expand-file-name org-clock-persist-file))
+	    (org-clock-in-resume t))
+	(if (file-readable-p filename)
+	    (progn
+	      (message "%s" "Restoring clock data")
+	      (setq org-clock-loaded t)
+	      (load-file filename)
+	      ;; load history
+	      (if (boundp 'stored-clock-history)
+		  (save-window-excursion
+		    (mapc (lambda (task)
+			    (org-clock-history-push (cdr task)
+						    (find-file (car task))))
+			  stored-clock-history)))
+	      ;; resume clock
+	      (if (and (boundp 'resume-clock) org-clock-persist
+		       (or (not org-clock-persist-query-resume)
+			   (y-or-n-p "Resume clock ("
+				     (with-current-buffer (find-file (car resume-clock))
+				       (progn (goto-char (cdr resume-clock))
+					      (looking-at org-complex-heading-regexp)
+					      (match-string 4))) ")")))
+		  (with-current-buffer (find-file (car resume-clock))
+		    (progn (goto-char (cdr resume-clock))
+			   (org-clock-in)))))
+	  (message "Not restoring clock data; %s not found"
+		   org-clock-persist-file)))))
+
+(defun org-clock-persistence-insinuate ()
+  "Set up hooks for clock persistence"
+  (add-hook 'org-mode-hook 'org-clock-load)
+  (add-hook 'kill-emacs-hook 'org-clock-save))
+
 (provide 'org-clock)
 (provide 'org-clock)
 
 
 ;; arch-tag: 7b42c5d4-9b36-48be-97c0-66a869daed4c
 ;; arch-tag: 7b42c5d4-9b36-48be-97c0-66a869daed4c