;;; time.el --- display time, load and mail indicator in mode line of Emacs -*-coding: utf-8 -*-
-;; Copyright (C) 1985, 86, 87, 93, 94, 96, 2000, 2001, 2002, 2003
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1996, 2000, 2001, 2002,
+;; 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;; Maintainer: FSF
;; 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 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; Facilities to display current time/date and a new-mail indicator
-;; in the Emacs mode line. The single entry point is `display-time'.
+;; in the Emacs mode line. The entry point is `display-time'.
+
+;; Display time world in a buffer, the entry point is
+;; `display-time-world'.
;;; Code:
(defgroup display-time nil
"Display time and load in mode line of Emacs."
- :group 'modeline
+ :group 'mode-line
:group 'mail)
(defcustom display-time-mail-file nil
"*File name of mail inbox file, for indicating existence of new mail.
-Non-nil and not a string means don't check for mail. nil means use
+Non-nil and not a string means don't check for mail; nil means use
default, which is system-dependent, and is the same as used by Rmail."
:type '(choice (const :tag "None" none)
(const :tag "Default" nil)
(defcustom display-time-24hr-format nil
"*Non-nil indicates time should be displayed as hh:mm, 0 <= hh <= 23.
-nil means 1 <= hh <= 12, and an AM/PM suffix is used."
+A value of nil means 1 <= hh <= 12, and an AM/PM suffix is used."
:type 'boolean
:group 'display-time)
"Time when mail file's file system was recorded to be down.
If that file system seems to be up, the value is nil.")
+(defcustom zoneinfo-style-world-list
+ '(("America/Los_Angeles" "Seattle")
+ ("America/New_York" "New York")
+ ("Europe/London" "London")
+ ("Europe/Paris" "Paris")
+ ("Asia/Calcutta" "Bangalore")
+ ("Asia/Tokyo" "Tokyo"))
+ "Alist of zoneinfo-style time zones and places for `display-time-world'.
+Each element has the form (TIMEZONE LABEL).
+TIMEZONE should be a string of the form AREA/LOCATION, where AREA is
+the name of a region -- a continent or ocean, and LOCATION is the name
+of a specific location, e.g., a city, within that region.
+LABEL is a string to display as the label of that TIMEZONE's time."
+ :group 'display-time
+ :type '(repeat (list string string))
+ :version "23.1")
+
+(defcustom legacy-style-world-list
+ '(("PST8PDT" "Seattle")
+ ("EST5EDT" "New York")
+ ("GMT0BST" "London")
+ ("CET-1CDT" "Paris")
+ ("IST-5:30" "Bangalore")
+ ("JST-9" "Tokyo"))
+ "Alist of traditional-style time zones and places for `display-time-world'.
+Each element has the form (TIMEZONE LABEL).
+TIMEZONE should be a string of the form:
+
+ std[+|-]offset[dst[offset][,date[/time],date[/time]]]
+
+See the documentation of the TZ environment variable on your system,
+for more details about the format of TIMEZONE.
+LABEL is a string to display as the label of that TIMEZONE's time."
+ :group 'display-time
+ :type '(repeat (list string string))
+ :version "23.1")
+
+(defcustom display-time-world-list
+ ;; Determine if zoneinfo style timezones are supported by testing that
+ ;; America/New York and Europe/London return different timezones.
+ (let (gmt nyt)
+ (set-time-zone-rule "America/New York")
+ (setq nyt (format-time-string "%z"))
+ (set-time-zone-rule "Europe/London")
+ (setq gmt (format-time-string "%z"))
+ (set-time-zone-rule nil)
+ (if (string-equal nyt gmt)
+ legacy-style-world-list
+ zoneinfo-style-world-list))
+ "Alist of time zones and places for `display-time-world' to display.
+Each element has the form (TIMEZONE LABEL).
+TIMEZONE should be in the format supported by `set-time-zone-rule' on
+your system. See the documentation of `zoneinfo-style-world-list' and
+\`legacy-style-world-list' for two widely used formats.
+LABEL is a string to display as the label of that TIMEZONE's time."
+ :group 'display-time
+ :type '(repeat (list string string))
+ :version "23.1")
+
+(defcustom display-time-world-time-format "%A %d %B %R %Z"
+ "Format of the time displayed, see `format-time-string'."
+ :group 'display-time
+ :type 'string
+ :version "23.1")
+
+(defcustom display-time-world-buffer-name "*wclock*"
+ "Name of the wclock buffer."
+ :group 'display-time
+ :type 'string
+ :version "23.1")
+
+(defcustom display-time-world-timer-enable t
+ "If non-nil, a timer will update the world clock."
+ :group 'display-time
+ :type 'boolean
+ :version "23.1")
+
+(defcustom display-time-world-timer-second 60
+ "Interval in seconds for updating the world clock."
+ :group 'display-time
+ :type 'integer
+ :version "23.1")
+
+(defvar display-time-world-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "q" 'kill-this-buffer)
+ map)
+ "Keymap of Display Time World mode")
+
;;;###autoload
(defun display-time ()
"Enable display of time, load level, and mail flag in mode lines.
(defcustom display-time-mail-face nil
"Face to use for `display-time-mail-string'.
If `display-time-use-mail-icon' is non-nil, the image's
-background colour is the background of this face. Set this to
-make the mail indicator stand out on a colour display."
- :group 'faces
+background color is the background of this face. Set this to
+make the mail indicator stand out on a color display."
+ :group 'mode-line-faces
:group 'display-time
:version "22.1"
:type '(choice (const :tag "None" nil) face))
;; Fixme: Default to icon on graphical display?
(defcustom display-time-use-mail-icon nil
- "Non-nil means use an icon as the mail indicator on a graphic display.
+ "Non-nil means use an icon as mail indicator on a graphic display.
Otherwise use `display-time-mail-string'. The icon may consume less
of the mode line. It is specified by `display-time-mail-icon'."
:group 'display-time
string))
(defcustom display-time-format nil
- "*A string specifying the format for displaying the time in the mode line.
+ "*String specifying format for displaying the time in the mode line.
See the function `format-time-string' for an explanation of
how to write this string. If this is nil, the defaults
depend on `display-time-day-and-date' and `display-time-24hr-format'."
(list :background bg)))))
'face display-time-mail-face
'help-echo "You have new mail; mouse-2: Read mail"
+ 'mouse-face 'mode-line-highlight
'local-map (make-mode-line-mouse-map 'mouse-2
read-mail-command)))
""))
- "*A list of expressions governing display of the time in the mode line.
+ "*List of expressions governing display of the time in the mode line.
For most purposes, you can control the time format using `display-time-format'
which is a more standard interface.
(concat (substring str 0 -2) "." (substring str -2))
'local-map (make-mode-line-mouse-map
'mouse-2 'display-time-next-load-average)
+ 'mouse-face 'mode-line-highlight
'help-echo (concat
"System load average for past "
(if (= 0 display-time-load-average)
;; Record that mail file is accessible.
(setq display-time-server-down-time nil)))))))
(24-hours (substring time 11 13))
- (hour (string-to-int 24-hours))
+ (hour (string-to-number 24-hours))
(12-hours (int-to-string (1+ (% (+ hour 11) 12))))
(am-pm (if (>= hour 12) "pm" "am"))
(minutes (substring time 14 16))
(remove-hook 'rmail-after-get-new-mail-hook
'display-time-event-handler)))
+
+(defun display-time-world-mode ()
+ "Major mode for buffer that displays times in various time zones.
+See `display-time-world'."
+ (interactive)
+ (kill-all-local-variables)
+ (setq
+ major-mode 'display-time-world-mode
+ mode-name "World clock")
+ (use-local-map display-time-world-mode-map))
+
+(defun display-time-world-display (alist)
+ "Replace current buffer text with times in various zones, based on ALIST."
+ (let ((inhibit-read-only t)
+ (buffer-undo-list t))
+ (erase-buffer)
+ (let ((max-width 0)
+ (result ()))
+ (unwind-protect
+ (dolist (zone alist)
+ (let* ((label (cadr zone))
+ (width (string-width label)))
+ (set-time-zone-rule (car zone))
+ (setq result
+ (append result
+ (list
+ label width
+ (format-time-string display-time-world-time-format))))
+ (when (> width max-width)
+ (setq max-width width))))
+ (set-time-zone-rule nil))
+ (while result
+ (insert (pop result)
+ (make-string (1+ (- max-width (pop result))) ?\s)
+ (pop result) "\n")))
+ (delete-backward-char 1)))
+
+;;;###autoload
+(defun display-time-world ()
+ "Enable updating display of times in various time zones.
+`display-time-world-list' specifies the zones.
+To turn off the world time display, go to that window and type `q'."
+ (interactive)
+ (when (and display-time-world-timer-enable
+ (not (get-buffer display-time-world-buffer-name)))
+ (run-at-time t display-time-world-timer-second 'display-time-world-timer))
+ (with-current-buffer (get-buffer-create display-time-world-buffer-name)
+ (display-time-world-display display-time-world-list))
+ (pop-to-buffer display-time-world-buffer-name)
+ (fit-window-to-buffer)
+ (display-time-world-mode))
+
+(defun display-time-world-timer ()
+ (if (get-buffer display-time-world-buffer-name)
+ (with-current-buffer (get-buffer display-time-world-buffer-name)
+ (display-time-world-display display-time-world-list))
+ ;; cancel timer
+ (let ((list timer-list))
+ (while list
+ (let ((elt (pop list)))
+ (when (equal (symbol-name (aref elt 5)) "display-time-world-timer")
+ (cancel-timer elt)))))))
+
(provide 'time)
;;; arch-tag: b9c1623f-b5cb-48e4-b650-482a4d23c5a6