Sync Org 7.9.2 from the commit tagged "release_7.9.2" in Org's Git repo.
[bpt/emacs.git] / lisp / org / org-timer.el
index a3bde0f..92aaf1c 100644 (file)
@@ -56,6 +56,22 @@ When 0, the user is prompted for a value."
   :version "24.1"
   :type 'number)
 
+(defcustom org-timer-display 'mode-line
+  "When a timer is running, org-mode can display it in the mode
+line and/or frame title.
+Allowed values are:
+
+both         displays in both mode line and frame title
+mode-line    displays only in mode line (default)
+frame-title  displays only in frame title
+nil          current timer is not displayed"
+  :group 'org-time
+  :type '(choice
+         (const :tag "Mode line" mode-line)
+         (const :tag "Frame title" frame-title)
+         (const :tag "Both" both)
+         (const :tag "None" nil)))
+
 (defvar org-timer-start-hook nil
   "Hook run after relative timer is started.")
 
@@ -66,7 +82,7 @@ When 0, the user is prompted for a value."
   "Hook run before relative timer is paused.")
 
 (defvar org-timer-continue-hook nil
- "Hook run after relative timer is continued.")
 "Hook run after relative timer is continued.")
 
 (defvar org-timer-set-hook nil
   "Hook run after countdown timer is set.")
@@ -114,6 +130,7 @@ the region 0:00:00."
               (org-timer-secs-to-hms (or delta 0)))
       (run-hooks 'org-timer-start-hook))))
 
+;;;###autoload
 (defun org-timer-pause-or-continue (&optional stop)
   "Pause or continue the relative timer.
 With prefix arg STOP, stop it entirely."
@@ -140,6 +157,7 @@ With prefix arg STOP, stop it entirely."
     (org-timer-set-mode-line 'pause)
     (message "Timer paused at %s" (org-timer-value-string)))))
 
+;;;###autoload
 (defun org-timer-stop ()
   "Stop the relative timer."
   (interactive)
@@ -181,7 +199,7 @@ it in the buffer."
 (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: ")
+   "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
@@ -224,7 +242,7 @@ it in the buffer."
      ;; Else, start a new list.
      (t
       (beginning-of-line)
-      (org-indent-line-function)
+      (org-indent-line)
       (insert  "- ")
       (org-timer (when arg '(4)))
       (insert ":: ")))))
@@ -270,32 +288,54 @@ If the integer is negative, the string will start with \"-\"."
 (defun org-timer-set-mode-line (value)
   "Set the mode-line display of the relative timer.
 VALUE can be `on', `off', or `pause'."
-  (or global-mode-string (setq global-mode-string '("")))
-  (or (memq 'org-timer-mode-line-string global-mode-string)
-      (setq global-mode-string
-           (append global-mode-string '(org-timer-mode-line-string))))
+  (when (or (eq org-timer-display 'mode-line)
+           (eq org-timer-display 'both))
+    (or global-mode-string (setq global-mode-string '("")))
+    (or (memq 'org-timer-mode-line-string global-mode-string)
+       (setq global-mode-string
+             (append global-mode-string '(org-timer-mode-line-string)))))
+  (when (or (eq org-timer-display 'frame-title)
+           (eq org-timer-display 'both))
+    (or (memq 'org-timer-mode-line-string frame-title-format)
+       (setq frame-title-format
+             (append frame-title-format '(org-timer-mode-line-string)))))
   (cond
    ((equal value 'off)
     (when org-timer-mode-line-timer
       (cancel-timer org-timer-mode-line-timer)
       (setq org-timer-mode-line-timer nil))
-    (setq global-mode-string
-         (delq 'org-timer-mode-line-string global-mode-string))
+    (when (or (eq org-timer-display 'mode-line)
+             (eq org-timer-display 'both))
+      (setq global-mode-string
+           (delq 'org-timer-mode-line-string global-mode-string)))
+    (when (or (eq org-timer-display 'frame-title)
+             (eq org-timer-display 'both))
+      (setq frame-title-format
+           (delq 'org-timer-mode-line-string frame-title-format)))
     (force-mode-line-update))
    ((equal value 'pause)
     (when org-timer-mode-line-timer
       (cancel-timer org-timer-mode-line-timer)
       (setq org-timer-mode-line-timer nil)))
    ((equal value 'on)
-    (or global-mode-string (setq global-mode-string '("")))
-    (or (memq 'org-timer-mode-line-string global-mode-string)
-       (setq global-mode-string
-             (append global-mode-string '(org-timer-mode-line-string))))
+    (when (or (eq org-timer-display 'mode-line)
+             (eq org-timer-display 'both))
+      (or global-mode-string (setq global-mode-string '("")))
+      (or (memq 'org-timer-mode-line-string global-mode-string)
+         (setq global-mode-string
+               (append global-mode-string '(org-timer-mode-line-string)))))
+    (when (or (eq org-timer-display 'frame-title)
+             (eq org-timer-display 'both))
+      (or (memq 'org-timer-mode-line-string frame-title-format)
+         (setq frame-title-format
+               (append frame-title-format '(org-timer-mode-line-string)))))
     (org-timer-update-mode-line)
     (when org-timer-mode-line-timer
-      (cancel-timer org-timer-mode-line-timer))
-    (setq org-timer-mode-line-timer
-         (run-with-timer 1 1 'org-timer-update-mode-line)))))
+      (cancel-timer org-timer-mode-line-timer)
+      (setq org-timer-mode-line-timer nil))
+    (when org-timer-display
+      (setq org-timer-mode-line-timer
+           (run-with-timer 1 1 'org-timer-update-mode-line))))))
 
 (defun org-timer-update-mode-line ()
   "Update the timer time in the mode line."
@@ -358,48 +398,48 @@ replace any running timer."
                          (number-to-string org-timer-default-timer))))))
     (if (not (string-match "[0-9]+" minutes))
        (org-timer-show-remaining-time)
-    (let* ((mins (string-to-number (match-string 0 minutes)))
-          (secs (* mins 60))
-          (hl (cond
-               ((string-match "Org Agenda" (buffer-name))
-                (let* ((marker (or (get-text-property (point) 'org-marker)
-                                   (org-agenda-error)))
-                       (hdmarker (or (get-text-property (point) 'org-hd-marker)
-                                     marker))
-                       (pos (marker-position marker)))
-                  (with-current-buffer (marker-buffer marker)
-                    (widen)
-                    (goto-char pos)
-                    (org-show-entry)
-                    (or (ignore-errors (org-get-heading))
-                        (concat "File:" (file-name-nondirectory (buffer-file-name)))))))
-               ((eq major-mode 'org-mode)
-                (or (ignore-errors (org-get-heading))
-                    (concat "File:" (file-name-nondirectory (buffer-file-name)))))
-               (t (error "Not in an Org buffer"))))
-          timer-set)
-      (if (or (and org-timer-current-timer
-                  (or (equal opt '(16))
-                      (y-or-n-p "Replace current timer? ")))
-             (not org-timer-current-timer))
-         (progn
-           (require 'org-clock)
-           (when org-timer-current-timer
-             (cancel-timer org-timer-current-timer))
-           (setq org-timer-current-timer
-                 (run-with-timer
-                  secs nil `(lambda ()
-                              (setq org-timer-current-timer nil)
-                              (org-notify ,(format "%s: time out" hl) t)
-                              (setq org-timer-timer-is-countdown nil)
-                              (org-timer-set-mode-line 'off)
-                              (run-hooks 'org-timer-done-hook))))
-           (run-hooks 'org-timer-set-hook)
-           (setq org-timer-timer-is-countdown t
-                 org-timer-start-time
-                 (time-add (current-time) (seconds-to-time (* mins 60))))
-           (org-timer-set-mode-line 'on))
-       (message "No timer set"))))))
+      (let* ((mins (string-to-number (match-string 0 minutes)))
+            (secs (* mins 60))
+            (hl (cond
+                 ((string-match "Org Agenda" (buffer-name))
+                  (let* ((marker (or (get-text-property (point) 'org-marker)
+                                     (org-agenda-error)))
+                         (hdmarker (or (get-text-property (point) 'org-hd-marker)
+                                       marker))
+                         (pos (marker-position marker)))
+                    (with-current-buffer (marker-buffer marker)
+                      (widen)
+                      (goto-char pos)
+                      (org-show-entry)
+                      (or (ignore-errors (org-get-heading))
+                          (concat "File:" (file-name-nondirectory (buffer-file-name)))))))
+                 ((derived-mode-p 'org-mode)
+                  (or (ignore-errors (org-get-heading))
+                      (concat "File:" (file-name-nondirectory (buffer-file-name)))))
+                 (t (error "Not in an Org buffer"))))
+            timer-set)
+       (if (or (and org-timer-current-timer
+                    (or (equal opt '(16))
+                        (y-or-n-p "Replace current timer? ")))
+               (not org-timer-current-timer))
+           (progn
+             (require 'org-clock)
+             (when org-timer-current-timer
+               (cancel-timer org-timer-current-timer))
+             (setq org-timer-current-timer
+                   (run-with-timer
+                    secs nil `(lambda ()
+                                (setq org-timer-current-timer nil)
+                                (org-notify ,(format "%s: time out" hl) t)
+                                (setq org-timer-timer-is-countdown nil)
+                                (org-timer-set-mode-line 'off)
+                                (run-hooks 'org-timer-done-hook))))
+             (run-hooks 'org-timer-set-hook)
+             (setq org-timer-timer-is-countdown t
+                   org-timer-start-time
+                   (time-add (current-time) (seconds-to-time (* mins 60))))
+             (org-timer-set-mode-line 'on))
+         (message "No timer set"))))))
 
 (provide 'org-timer)