فهرست منبع

Implement timer for timed notes.

This patch implements a relative time for taking timed notes, useful
for example while watching a video, or during a meeting which is also
recorded.  Here are the new commands:

    - `C-c C-x .' ::
      Insert a relative time into the buffer.  The first time
      you use this, the timer will be started.  When called
      with a prefix argument, the timer is reset to 0.

    - `C-c C-x -' ::
      Insert a description list item with the current relative
      time.  With a prefix argument, first reset the timer to 0.

    - `C-c C-x 0' ::
      Reset the timer without inserting anything into the buffer.
      By default, the timer is reset to 0.  When called with a
      `C-u' prefix, reset the timer to specific starting
      offset.  The user is prompted for the offset, with a
      default taken from a timer string at point, if any, So this
      can be used to restart taking notes after a break in the
      process.  When called with a double prefix argument
      `C-c C-u', change all timer strings in the active
      region by a certain amount.  This can be used to fix timer
      strings if the timer was not started at exactly the right
      moment.
Carsten Dominik 16 سال پیش
والد
کامیت
4b2d3c6feb
6فایلهای تغییر یافته به همراه272 افزوده شده و 13 حذف شده
  1. 37 1
      ORGWEBPAGE/Changes.org
  2. 1 9
      doc/ChangeLog
  3. 34 2
      doc/org.texi
  4. 2 0
      lisp/ChangeLog
  5. 176 0
      lisp/org-timer.el
  6. 22 1
      lisp/org.el

+ 37 - 1
ORGWEBPAGE/Changes.org

@@ -11,11 +11,47 @@
 #+LINK_HOME: http://orgmode.org
 
 
-* Version 6.13
+* Version 6.14 (in preparation)
   :PROPERTIES:
   :VISIBILITY: content
   :END:
 
+** Overview
+
+** Details
+
+*** New relative timer to support timed notes
+
+    Org now supports taking timed notes, useful for example while
+    watching a video, or during a meeting which is also recorded.
+
+    - =C-c C-x .= :: 
+      Insert a relative time into the buffer.  The first time
+      you use this, the timer will be started.  When called
+      with a prefix argument, the timer is reset to 0.
+
+    - =C-c C-x -= :: 
+      Insert a description list item with the current relative
+      time.  With a prefix argument, first reset the timer to 0.
+
+    - =C-c C-x 0= :: 
+      Reset the timer without inserting anything into the buffer.
+      By default, the timer is reset to 0.  When called with a
+      =C-u= prefix, reset the timer to specific starting
+      offset.  The user is prompted for the offset, with a
+      default taken from a timer string at point, if any, So this
+      can be used to restart taking notes after a break in the
+      process.  When called with a double prefix argument
+      =C-c C-u=, change all timer strings in the active
+      region by a certain amount.  This can be used to fix timer
+      strings if the timer was not started at exactly the right
+      moment.
+
+    Thanks to Alan Dove, Adam Spiers, and Alan Davis for
+    contributions to this idea.
+
+* Version 6.13
+
 ** Overview
 
    - Keybindings in Remember buffers can be configured

+ 1 - 9
doc/ChangeLog

@@ -2,15 +2,7 @@
 
 	* org.texi (Project alist): Add info about the publishing sequence
 	of components.
-
-
-
-
-
-
-
-
-
+	(Effort estimates): Document the new relativer timer.
 
 2008-11-24  Carsten Dominik  <carsten.dominik@gmail.com>
 

+ 34 - 2
doc/org.texi

@@ -219,6 +219,7 @@ Dates and Times
 * Deadlines and scheduling::    Planning your work
 * Clocking work time::          Tracking how long you spend on a task
 * Effort estimates::            Planning work effort in advance
+* Relative timer::              Notes with a running timer
 
 Creating timestamps
 
@@ -4262,6 +4263,7 @@ is used in a much wider sense.
 * Deadlines and scheduling::    Planning your work
 * Clocking work time::          Tracking how long you spend on a task
 * Effort estimates::            Planning work effort in advance
+* Relative timer::              Notes with a running timer
 @end menu
 
 
@@ -4890,9 +4892,9 @@ The @kbd{l} key may be used in the timeline (@pxref{Timeline}) and in
 the agenda (@pxref{Weekly/daily agenda}) to show which tasks have been
 worked on or closed during a day.
 
-@node Effort estimates,  , Clocking work time, Dates and Times
+@node Effort estimates, Relative timer, Clocking work time, Dates and Times
 @section Effort estimates
-@cindex Effort estimates
+@cindex effort estimates
 
 If you want to plan your work in a very detailed way, or if you need to
 produce offers with quotations of the estimated work effort, you may want to
@@ -4936,6 +4938,36 @@ with the @kbd{/} key in the agenda (@pxref{Agenda commands}).  If you have
 these estimates defined consistently, two or three key presses will narrow
 down the list to stuff that fits into an available time slot.
 
+@node Relative timer,  , Effort estimates, Dates and Times
+@section Taking notes with a relative timer
+@cindex relative timer
+
+When taking notes during, for example, a meeting or a video viewing, it can
+be useful to have access to times relative to a starting time.  Org provides
+such a relative timer and make it easy to create timed notes.
+
+@table @kbd
+@kindex C-c C-x .
+@item C-c C-x .
+Insert a relative time into the buffer.  The first time you use this, the
+timer will be started.  When called with a prefix argument, the timer is
+restarted. 
+@kindex C-c C-x -
+@item C-c C-x -
+Insert a description list item with the current relative time.  With a prefix
+argument, first reset the timer to 0.
+@kindex C-c C-x 0
+@item C-c C-x 0
+Reset the timer without inserting anything into the buffer.  By default, the
+timer is reset to 0.  When called with a @kbd{C-u} prefix, reset the timer to
+specific starting offset.  The user is prompted for the offset, with a
+default taken from a timer string at point, if any, So this can be used to
+restart taking notes after a break in the process.  When called with a double
+prefix argument @kbd{C-c C-u}, change all timer strings in the active region
+by a certain amount.  This can be used to fix timer strings if the timer was
+not started at exactly the right moment.
+@end table
+
 @node Capture, Agenda Views, Dates and Times, Top
 @chapter Capture
 @cindex capture

+ 2 - 0
lisp/ChangeLog

@@ -1,5 +1,7 @@
 2008-11-25  Carsten Dominik  <carsten.dominik@gmail.com>
 
+	* org-timer.el: New file.
+
 	* org-publish.el (org-publish-org-index): Only exclude the index
 	file in the main directory from being added to the site-map.
 	(org-publish-get-project-from-filename): If the current project is

+ 176 - 0
lisp/org-timer.el

@@ -0,0 +1,176 @@
+;;; org-clock.el --- The time clocking code for Org-mode
+
+;; Copyright (C) 2008 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Keywords: outlines, hypermedia, calendar, wp
+;; Homepage: http://orgmode.org
+;; Version: 6.13a
+;;
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+
+;; This file contains the relative timer code for Org-mode
+
+(defconst org-timer-re "\\([-+]?[0-9]+\\):\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)"
+  "Regular expression used to match timer stamps.")
+
+(defcustom org-timer-format "%s "
+  "The format to insert the time of the timer.
+This format must contain one instance of \"%s\" which will be replaced by
+the value of the relative timer."
+  :group 'org-time
+  :type 'string)
+
+;;;###autoload
+(defun org-timer-start (&optional offset)
+  "Set the starting time for the relative timer to now.
+When called with prefix argument OFFSET, prompt the user for an offset time,
+with the default taken from a timer stamp at point, if any.
+If OFFSET is a string or an integer, it is directly taken to be the offset
+without user interaction.
+When called with a double prefix arg, all timer strings in the active
+region will be shifted by a specific amount.  You will be prompted for
+the amount, with the default to make the first timer string in
+the region 0:00:00."
+  (interactive "P")
+  (if (equal offset '(16))
+      (call-interactively 'org-timer-change-times-in-region)
+    (let (delta des s)
+      (if (not offset)
+	  (setq org-timer-start-time (current-time))
+	(cond
+	 ((integerp offset) (setq delta offset))
+	 ((stringp offset) (setq delta (org-timer-hms-to-secs offset)))
+	 (t
+	  (setq def (if (org-in-regexp org-timer-re)
+			(match-string 0)
+		      "0:00:00")
+		s (read-string 
+		   (format "Restart timer with offset [%s]: " def)))
+	  (unless (string-match "\\S-" s) (setq s def))
+	  (setq delta (org-timer-hms-to-secs (org-timer-fix-incomplete s)))))
+	(setq org-timer-start-time
+	      (seconds-to-time
+	       (-
+		(time-to-seconds (current-time))
+		(org-timer-hms-to-secs s)))))
+      (message "Timer start time set to %s, current value is %s"
+	       (format-time-string "%T" org-timer-start-time)
+	       (org-timer-secs-to-hms (or delta 0))))))
+
+;;;###autoload
+(defun org-timer (&optional restart)
+  "Insert a H:MM:SS string from the timer into the buffer.
+The first time this command is used, the timer is started.  When used with
+a `C-u' prefix, force restarting the timer.
+When used with a double prefix arg `C-u C-u', change all the timer string
+in the region by a fixed amount.  This can be used to recalibrate a timer
+that was not started at the correct moment."
+  (interactive "P")
+  (if (equal restart '(4)) (org-timer-start))
+  (or org-timer-start-time (org-timer-start))
+  (insert (format
+	   org-timer-format
+	   (org-timer-secs-to-hms
+	    (floor
+	     (- (time-to-seconds (current-time))
+		(time-to-seconds org-timer-start-time))))))))
+
+;;;###autoload
+(defun org-timer-change-times-in-region (beg end delta)
+  "Change all h:mm:ss time in region by a DELTA."
+  (interactive
+   "r\nsEnter time difference like \"-1:08:26\". Default is first time to zero: ")
+  (let ((re "[-+]?[0-9]+:[0-9]\\{2\\}:[0-9]\\{2\\}") p)
+    (unless (string-match "\\S-" delta)
+      (save-excursion
+	(goto-char beg)
+	(when (re-search-forward re end t)
+	  (setq delta (match-string 0))
+	  (if (equal (string-to-char delta) ?-)
+	      (setq delta (substring delta 1))
+	    (setq delta (concat "-" delta))))))
+    (setq delta (my-hms-to-secs (org-timer-fix-incomplete delta)))
+    (when (= delta 0) (error "No change"))
+    (save-excursion
+      (goto-char end)
+      (while (re-search-backward re beg t)
+	(setq p (point))
+	(replace-match
+	 (save-match-data
+	   (org-timer-secs-to-hms (+ (org-timer-hms-to-secs (match-string 0)) delta)))
+	 t t)
+	(goto-char p)))))
+
+;;;###autoload
+(defun org-timer-item (arg)
+  "Insert a description-type item with the curren timer value."
+  (interactive "P")
+  (let ((ind 0))
+    (save-excursion
+      (skip-chars-backward " \n\t")
+      (condition-case nil
+	  (progn
+	    (org-beginning-of-item)
+	    (setq ind (org-get-indentation)))
+	(error nil)))
+    (or (bolp) (newline))
+    (org-indent-line-to ind)
+    (insert "- ")
+    (org-timer (if arg '(4)))
+    (insert ":: ")))
+
+(defun org-timer-fix-incomplete (hms)
+  "If hms is a H:MM:SS string with missing hour or hour and minute, fix it."
+  (if (string-match "\\(?:\\([0-9]+:\\)?\\([0-9]+:\\)\\)?\\([0-9]+\\)" hms)
+      (replace-match
+       (format "%d:%02d:%02d"
+	       (if (match-end 1) (string-to-int (match-string 1 hms)) 0)
+	       (if (match-end 2) (string-to-int (match-string 2 hms)) 0)
+	       (string-to-int (match-string 3 hms)))
+       t t hms)
+    (error "Canot parse HMS string \"%s\"" hms)))
+
+(defun org-timer-hms-to-secs (hms)
+  "Convert h:mm:ss string to an integer time.
+If the string starts with a minus sign, the integer will be negative."
+  (if (not (string-match
+	    "\\([-+]?[0-9]+\\):\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)"
+	    hms))
+      0
+    (let* ((h (string-to-int (match-string 1 hms)))
+	   (m (string-to-int (match-string 2 hms)))
+	   (s (string-to-int (match-string 3 hms)))
+	   (sign (equal (substring (match-string 1 hms) 0 1) "-")))
+      (setq h (abs h))
+      (* (if sign -1 1) (+ s (* 60 (+ m (* 60 h))))))))
+
+(defun org-timer-secs-to-hms (s)
+  "Convert integer S into h:mm:ss.
+If the integer is negative, the strig will start with \"-\"."
+  (let (sign m h)
+    (setq sign (if (< s 0) "-" "")
+	  s (abs s)
+	  m (/ s 60) s (- s (* 60 m))
+	  h (/ m 60) m (- m (* 60 h)))
+    (format "%s%d:%02d:%02d" sign h m s)))
+
+;; arch-tag: 97538f8c-3871-4509-8f23-1e7b3ff3d107
+
+;;; org-timer.el ends here

+ 22 - 1
lisp/org.el

@@ -2640,6 +2640,19 @@ If yes, offer to stop it and to save the buffer with the changes."
   (when (org-match-line "#\\+BEGIN: clocktable\\>")
     (org-clocktable-shift dir n)))
 
+;; Autoload org-timer.el
+
+(declare-function org-clock-save-markers-for-cut-and-paste "org-clock"
+		  (beg end))
+(declare-function org-update-mode-line "org-clock" ())
+
+(eval-and-compile
+  (org-autoload
+   "org-timer"
+   '(org-timer-start org-timer org-timer-item
+		     org-timer-change-times-in-region)))
+
+
 ;; Autoload archiving code
 ;; The stuff that is needed for cycling and tags has to be defined here.
 
@@ -12418,6 +12431,10 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]."
 (org-defkey org-mode-map "\C-c\C-xp"    'org-set-property)
 (org-defkey org-mode-map "\C-c\C-xi"    'org-insert-columns-dblock)
 
+(org-defkey org-mode-map "\C-c\C-x."    'org-timer)
+(org-defkey org-mode-map "\C-c\C-x-"    'org-timer-item)
+(org-defkey org-mode-map "\C-c\C-x0"    'org-timer-start)
+
 (define-key org-mode-map "\C-c\C-x\C-c" 'org-columns)
 
 (when (featurep 'xemacs)
@@ -13191,7 +13208,11 @@ See the individual commands for more information."
       :style radio :selected org-display-custom-times]
      "--"
      ["Goto Calendar" org-goto-calendar t]
-     ["Date from Calendar" org-date-from-calendar t])
+     ["Date from Calendar" org-date-from-calendar t]
+     "--"
+     ["Start/restart timer" org-timer-start t]
+     ["Insert timer string" org-timer t]
+     ["Insert timer item" org-timer-item t])
     ("Logging work"
      ["Clock in" org-clock-in t]
      ["Clock out" org-clock-out t]