]> code.delx.au - gnu-emacs/blobdiff - lisp/time-stamp.el
(help-make-xrefs): Default info references to an
[gnu-emacs] / lisp / time-stamp.el
index a6aeb2a4d5532c026ac6071fedcd49c0be81955a..b7a85400d72290b0eb4012a5f68a7f2349c8f797 100644 (file)
@@ -2,7 +2,7 @@
 
 ;; Copyright 1989, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
 
-;; Maintainer's Time-stamp: <1997-06-08 16:45:41 gildea>
+;; Maintainer's Time-stamp: <1998-03-04 14:14:19 gildea>
 ;; Maintainer: Stephen Gildea <gildea@alum.mit.edu>
 ;; Keywords: tools
 
   :group 'data
   :group 'extensions)
 
-(defcustom time-stamp-active t
-  "*Non-nil to enable time-stamping of buffers by \\[time-stamp].
-Can be toggled by \\[time-stamp-toggle-active].
-See also the variable `time-stamp-warn-inactive'."
-  :type 'boolean
-  :group 'time-stamp)
-
-(defcustom time-stamp-warn-inactive t
-  "Non-nil to have \\[time-stamp] warn if a buffer did not get time-stamped.
-A warning is printed if `time-stamp-active' is nil and the buffer contains
-a time stamp template that would otherwise have been updated."
-  :type 'boolean
-  :group 'time-stamp)
-
-(defcustom time-stamp-old-format-warn 'ask
-  "Action to take if `time-stamp-format' is an old-style list.
-If `error', the format is not used.  If `ask', the user is queried about
-using the time-stamp-format.  If `warn', a warning is displayed.
-If nil, no notification is given."
-  :type '(choice (const :tag "No notification" nil)
-                 (const :tag "Don't use the format" error)
-                 (const ask) (const warn))
-  :group 'time-stamp)
-
 (defcustom time-stamp-format "%:y-%02m-%02d %02H:%02M:%02S %u"
   "*Format of the string inserted by \\[time-stamp].
 The value may be a string or a list.  Lists are supported only for
@@ -93,6 +69,7 @@ Non-date items:
 %f   file name without directory       %F  gives absolute pathname
 %s   system name
 %u   user's login name
+%U   user's full name
 %h   mail host name
 
 Decimal digits between the % and the type character specify the
@@ -110,12 +87,42 @@ historical default."
   :type 'string
   :group 'time-stamp)
 
+(defcustom time-stamp-active t
+  "*Non-nil to enable time-stamping of buffers by \\[time-stamp].
+Can be toggled by \\[time-stamp-toggle-active].
+See also the variable `time-stamp-warn-inactive'."
+  :type 'boolean
+  :group 'time-stamp)
 
+(defcustom time-stamp-warn-inactive t
+  "Non-nil to have \\[time-stamp] warn if a buffer did not get time-stamped.
+A warning is printed if `time-stamp-active' is nil and the buffer contains
+a time stamp template that would otherwise have been updated."
+  :type 'boolean
+  :group 'time-stamp)
+
+(defcustom time-stamp-old-format-warn 'ask
+  "Action to take if `time-stamp-format' is an old-style list.
+If `error', the format is not used.  If `ask', the user is queried about
+using the time-stamp-format.  If `warn', a warning is displayed.
+If nil, no notification is given."
+  :type '(choice (const :tag "No notification" nil)
+                 (const :tag "Don't use the format" error)
+                 (const ask) (const warn))
+  :group 'time-stamp)
+
+(defcustom time-stamp-time-zone nil
+  "If non-nil, a string naming the timezone to be used by \\[time-stamp].
+Format is the same as that used by the environment variable TZ on your system."
+  :type '(choice (const nil) string)
+  :group 'time-stamp)
 
-;;; Do not change time-stamp-line-limit, time-stamp-start, or
-;;; time-stamp-end in your .emacs or you will be incompatible
-;;; with other people's files!  If you must change them,
-;;; do so only in the local variables section of the file itself.
+
+;;; Do not change time-stamp-line-limit, time-stamp-start,
+;;; time-stamp-end, or time-stamp-pattern in your .emacs
+;;; or you will be incompatible with other people's files!
+;;; If you must change them, do so only in the local variables
+;;; section of the file itself.
 
 
 (defvar time-stamp-line-limit 8            ;Do not change!
@@ -152,6 +159,36 @@ with other people's files!  If you must change them for some application,
 do so in the local variables section of the time-stamped file itself.")
 
 
+(defvar time-stamp-pattern "%%"                ;Do not change!
+  "Convenience variable setting all time-stamp location and format variables.
+This string has four parts, each of which is optional.
+These four parts set time-stamp-line-limit, time-stamp-start,
+time-stamp-format, and time-stamp-end.  See the documentation
+for each of these variables for details.
+
+The first part is a number followed by a slash; the number sets the number
+of lines at the beginning (negative counts from end) of the file searched
+for the time-stamp.  The number and the slash may be omitted to use the
+normal value.
+
+The second part is a regexp identifying the pattern preceding the time stamp.
+This part may be omitted to use the normal pattern.
+
+The third part specifies the format of the time-stamp inserted.  See
+the documentation for time-stamp-format for details.  Specify this
+part as \"%%\" to use the normal format.
+
+The fourth part is a regexp identifying the pattern following the time stamp.
+This part may be omitted to use the normal pattern.
+
+As an example, the default behavior can be specified something like this:
+\"8/Time-stamp: [\\\"<]%:y-%02m-%02d %02H:%02M:%02S %u[\\\">]\"
+
+Do not change `time-stamp-pattern' for yourself or you will be incompatible
+with other people's files!  Set it only in the local variables section
+of the time-stamped file itself.")
+
+
 
 ;;;###autoload
 (defun time-stamp ()
@@ -164,7 +201,7 @@ look like one of the following:
       Time-stamp: <>
       Time-stamp: \" \"
 The time stamp is written between the brackets or quotes:
-      Time-stamp: <1996-07-18 10:20:51 gildea>
+      Time-stamp: <1998-02-18 10:20:51 gildea>
 The time stamp is updated only if the variable `time-stamp-active' is non-nil.
 The format of the time stamp is set by the variable `time-stamp-format'.
 The variables `time-stamp-line-limit', `time-stamp-start',
@@ -174,10 +211,26 @@ and `time-stamp-end' control finding the template."
        (start nil)
        (end nil)
        search-limit
-       (line-limit time-stamp-line-limit))
+       (line-limit time-stamp-line-limit)
+       (ts-start time-stamp-start)
+       (ts-format time-stamp-format)
+       (ts-end time-stamp-end))
+    (if (stringp time-stamp-pattern)
+       (progn
+         (string-match "\\`\\(\\(-?[0-9]+\\)/\\)?\\([^%]+\\)?\\(\\(.\\|\n\\)*%[-.,:@+_ #^()0-9]*[A-Za-z%]\\)?\\([^%]+\\)?\\'" time-stamp-pattern)
+         (and (match-beginning 2)
+              (setq line-limit
+                    (string-to-int (match-string 2 time-stamp-pattern))))
+         (and (match-beginning 3)
+              (setq ts-start (match-string 3 time-stamp-pattern)))
+         (and (match-beginning 4)
+              (not (string-equal (match-string 4 time-stamp-pattern) "%%"))
+              (setq ts-format (match-string 4 time-stamp-pattern)))
+         (and (match-beginning 6)
+              (setq ts-end (match-string 6 time-stamp-pattern)))))
     (cond ((not (integerp line-limit))
           (setq line-limit 8)
-          (message "time-stamp-line-limit is not a number")
+          (message "time-stamp-line-limit is not an integer")
           (sit-for 1)))
     (save-excursion
       (save-restriction
@@ -193,41 +246,41 @@ and `time-stamp-end' control finding the template."
        (goto-char start)
        (while (and (< (point) search-limit)
                    (not end)
-                   (re-search-forward time-stamp-start search-limit 'move))
+                   (re-search-forward ts-start search-limit 'move))
          (setq start (point))
          (end-of-line)
          (let ((line-end (point)))
            (goto-char start)
-           (if (re-search-forward time-stamp-end line-end 'move)
+           (if (re-search-forward ts-end line-end 'move)
                (setq end (match-beginning 0)))))))
-       (if end
-           (progn
-             ;; do all warnings outside save-excursion
-             (cond
-              ((not time-stamp-active)
-               (if time-stamp-warn-inactive
-                   ;; don't signal an error in a write-file-hook
-                   (progn
-                     (message "Warning: time-stamp-active is off; did not time-stamp buffer.")
-                     (sit-for 1))))
-              ((not (and (stringp time-stamp-start)
-                         (stringp time-stamp-end)))
-               (message "time-stamp-start or time-stamp-end is not a string")
-               (sit-for 1))
-              (t
-               (let ((new-time-stamp (time-stamp-string)))
-                 (if (stringp new-time-stamp)
-                     (save-excursion
-                       (save-restriction
-                         (widen)
-                         (delete-region start end)
-                         (goto-char start)
-                         (insert-and-inherit new-time-stamp)
-                         (setq end (point))
-                         ;; remove any tabs used to format time stamp
-                         (goto-char start)
-                         (if (search-forward "\t" end t)
-                             (untabify start end)))))))))))
+    (if end
+       (progn
+         ;; do all warnings outside save-excursion
+         (cond
+          ((not time-stamp-active)
+           (if time-stamp-warn-inactive
+               ;; don't signal an error in a write-file-hook
+               (progn
+                 (message "Warning: time-stamp-active is off; did not time-stamp buffer.")
+                 (sit-for 1))))
+          ((not (and (stringp ts-start)
+                     (stringp ts-end)))
+           (message "time-stamp-start or time-stamp-end is not a string")
+           (sit-for 1))
+          (t
+           (let ((new-time-stamp (time-stamp-string ts-format)))
+             (if (stringp new-time-stamp)
+                 (save-excursion
+                   (save-restriction
+                     (widen)
+                     (delete-region start end)
+                     (goto-char start)
+                     (insert-and-inherit new-time-stamp)
+                     (setq end (point))
+                     ;; remove any tabs used to format time stamp
+                     (goto-char start)
+                     (if (search-forward "\t" end t)
+                         (untabify start end)))))))))))
   ;; be sure to return nil so can be used on write-file-hooks
   nil)
 
@@ -267,7 +320,6 @@ With arg, turn time stamping on if and only if arg is positive."
        cur-char
        (prev-char nil)
        (result "")
-       field-index
        field-width
        field-result
        alt-form change-case require-padding
@@ -280,7 +332,7 @@ With arg, turn time stamping on if and only if arg is positive."
       (cond
        ((eq cur-char ?%)
        ;; eat any additional args to allow for future expansion
-       (setq alt-form nil change-case nil require-padding nil)
+       (setq alt-form nil change-case nil require-padding nil field-width "")
        (while (progn
                 (setq ind (1+ ind))
                 (setq cur-char (if (< ind fmt-len)
@@ -298,23 +350,25 @@ With arg, turn time stamping on if and only if arg is positive."
                              (> paren-level 0))
                         (setq paren-level (1- paren-level))
                       (and (> paren-level 0)
-                           (< ind fmt-len)))))
+                           (< ind fmt-len)))
+                    (if (and (<= ?0 cur-char) (>= ?9 cur-char))
+                        ;; get format width
+                        (let ((field-index ind))
+                          (while (progn
+                                   (setq ind (1+ ind))
+                                   (setq cur-char (if (< ind fmt-len)
+                                                      (aref format ind)
+                                                    ?\0))
+                                   (and (<= ?0 cur-char) (>= ?9 cur-char))))
+                          (setq field-width (substring format field-index ind))
+                          (setq ind (1- ind))
+                          t))))
          (setq prev-char cur-char)
          ;; some characters we actually use
          (cond ((eq cur-char ?:)
                 (setq alt-form t))
                ((eq cur-char ?#)
                 (setq change-case t))))
-       ;; get format width
-       (setq field-index ind)
-       (setq ind (1- ind))
-       (while (progn
-                (setq ind (1+ ind))
-                (setq cur-char (if (< ind fmt-len)
-                                   (aref format ind)
-                                 ?\0))
-                (and (<= ?0 cur-char) (>= ?9 cur-char))))
-       (setq field-width (substring format field-index ind))
        (setq field-result
        (cond
         ((eq cur-char ?%)
@@ -392,6 +446,8 @@ With arg, turn time stamping on if and only if arg is positive."
          (system-name))
         ((eq cur-char ?u)              ;user name
          (user-login-name))
+        ((eq cur-char ?U)              ;user full name
+         (user-full-name))
         ((eq cur-char ?h)              ;mail host name
          (time-stamp-mail-host-name))
         ))
@@ -456,13 +512,25 @@ The new forms being recommended now will continue to work then.")
             "The following obsolescent time-stamp-format construct(s) were found:\n\n")))
       (insert "\"" old-form "\" -- use " new-form "\n"))
     (display-buffer "*Time-stamp-compatibility*"))))
-  
 
 
-(defun time-stamp-string ()
-  "Generate the new string to be inserted by \\[time-stamp]."
-  (if (stringp time-stamp-format)
-      (format-time-string (time-stamp-string-preprocess time-stamp-format))
+
+(defun time-stamp-string (&optional ts-format)
+  "Generate the new string to be inserted by \\[time-stamp].
+Optionally use FORMAT."
+  (or ts-format
+      (setq ts-format time-stamp-format))
+  (if (stringp ts-format)
+      (if (stringp time-stamp-time-zone)
+         (let ((real-time-zone (getenv "TZ")))
+           (unwind-protect
+               (progn
+                 (setenv "TZ" time-stamp-time-zone)
+                 (format-time-string
+                  (time-stamp-string-preprocess ts-format)))
+             (setenv "TZ" real-time-zone)))
+       (format-time-string
+        (time-stamp-string-preprocess ts-format)))
     ;; handle version 1 compatibility
     (cond ((or (eq time-stamp-old-format-warn 'error)
               (and (eq time-stamp-old-format-warn 'ask)
@@ -474,7 +542,7 @@ The new forms being recommended now will continue to work then.")
           (cond ((eq time-stamp-old-format-warn 'warn)
                  (message "Obsolescent time-stamp-format type; should be string")
                  (sit-for 1)))
-          (time-stamp-fconcat time-stamp-format " ")))))
+          (time-stamp-fconcat ts-format " ")))))
 
 (defconst time-stamp-no-file "(no file)"
   "String to use when the buffer is not associated with a file.")