aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarl Heuer1999-08-27 01:47:33 +0000
committerKarl Heuer1999-08-27 01:47:33 +0000
commit55ac4d11d177514359f6ff32d3e2268fce47f438 (patch)
tree1281f1975ba851c9cff193b302e6890cf4965188
parentf8b7c3516fa19fe12e4fef0c2b2e297c3eb5fa6c (diff)
downloademacs-55ac4d11d177514359f6ff32d3e2268fce47f438.tar.gz
emacs-55ac4d11d177514359f6ff32d3e2268fce47f438.zip
Put quote-backquote around all symbol names
in doc strings, for mousing. (time-stamp): support multi-line patterns. (time-stamp-inserts-lines): new variable. (time-stamp-count): new variable. (time-stamp-string-preprocess): fixed bug where "%%a" becomes "Thu" instead of "%a".
-rw-r--r--lisp/time-stamp.el244
1 files changed, 164 insertions, 80 deletions
diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el
index a9c8b1d31f8..5ac4d49f262 100644
--- a/lisp/time-stamp.el
+++ b/lisp/time-stamp.el
@@ -2,7 +2,7 @@
2 2
3;; Copyright 1989, 1993, 1994, 1995, 1997 Free Software Foundation, Inc. 3;; Copyright 1989, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
4 4
5;; Maintainer's Time-stamp: <1999-01-06 11:06:03 gildea> 5;; Maintainer's Time-stamp: <1999-06-26 15:12:53 gildea>
6;; Maintainer: Stephen Gildea <gildea@alum.mit.edu> 6;; Maintainer: Stephen Gildea <gildea@alum.mit.edu>
7;; Keywords: tools 7;; Keywords: tools
8 8
@@ -73,12 +73,12 @@ Non-date items:
73 73
74Decimal digits between the % and the type character specify the 74Decimal digits between the % and the type character specify the
75field width. Strings are truncated on the right; years on the left. 75field width. Strings are truncated on the right; years on the left.
76A leading zero causes numbers to be zero-filled. 76A leading zero in the field width zero-fills a number.
77 77
78For example, to get the format used by the `date' command, 78For example, to get the format used by the `date' command,
79use \"%3a %3b %2d %02H:%02M:%02S %Z %:y\". 79use \"%3a %3b %2d %02H:%02M:%02S %Z %:y\".
80 80
81In the future these formats will be aligned more with format-time-string. 81In the future these formats will be aligned more with `format-time-string'.
82Because of this transition, the default padding for numeric formats will 82Because of this transition, the default padding for numeric formats will
83change in a future version. Therefore either a padding width should be 83change in a future version. Therefore either a padding width should be
84specified, or the : modifier should be used to explicitly request the 84specified, or the : modifier should be used to explicitly request the
@@ -95,8 +95,8 @@ See also the variable `time-stamp-warn-inactive'."
95 95
96(defcustom time-stamp-warn-inactive t 96(defcustom time-stamp-warn-inactive t
97 "Non-nil to have \\[time-stamp] warn if a buffer did not get time-stamped. 97 "Non-nil to have \\[time-stamp] warn if a buffer did not get time-stamped.
98A warning is printed if `time-stamp-active' is nil and the buffer contains 98A warning is printed if `time-stamp-active' disables time stamping and the
99a time stamp template that would otherwise have been updated." 99buffer contains a template that would otherwise have been updated."
100 :type 'boolean 100 :type 'boolean
101 :group 'time-stamp) 101 :group 'time-stamp)
102 102
@@ -118,16 +118,16 @@ Format is the same as that used by the environment variable TZ on your system."
118 118
119 119
120;;; Do not change time-stamp-line-limit, time-stamp-start, 120;;; Do not change time-stamp-line-limit, time-stamp-start,
121;;; time-stamp-end, or time-stamp-pattern in your .emacs 121;;; time-stamp-end, time-stamp-pattern, time-stamp-inserts-lines,
122;;; or you will be incompatible with other people's files! 122;;; or time-stamp-count in your .emacs or you will be incompatible
123;;; If you must change them, do so only in the local variables 123;;; with other people's files! If you must change them, do so only
124;;; section of the file itself. 124;;; in the local variables section of the file itself.
125 125
126 126
127(defvar time-stamp-line-limit 8 ;Do not change! 127(defvar time-stamp-line-limit 8 ;Do not change!
128 "Lines of a file searched; positive counts from start, negative from end. 128 "Lines of a file searched; positive counts from start, negative from end.
129The patterns `time-stamp-start' and `time-stamp-end' must be found on one 129The patterns `time-stamp-start' and `time-stamp-end' must be found in
130of the first (last) `time-stamp-line-limit' lines of the file for the 130the first (last) `time-stamp-line-limit' lines of the file for the
131file to be time-stamped by \\[time-stamp]. A value of 0 searches the 131file to be time-stamped by \\[time-stamp]. A value of 0 searches the
132entire buffer (use with care). 132entire buffer (use with care).
133 133
@@ -150,20 +150,52 @@ do so in the local variables section of the time-stamped file itself.")
150(defvar time-stamp-end "\\\\?[\">]" ;Do not change! 150(defvar time-stamp-end "\\\\?[\">]" ;Do not change!
151 "Regexp marking the text after the time stamp. 151 "Regexp marking the text after the time stamp.
152\\[time-stamp] deletes the text between the first match of `time-stamp-start' 152\\[time-stamp] deletes the text between the first match of `time-stamp-start'
153and the following match of `time-stamp-end' on the same line, 153and the following match of `time-stamp-end', then writes the
154then writes the time stamp specified by `time-stamp-format' between them. 154time stamp specified by `time-stamp-format' between them.
155 155
156Do not change `time-stamp-line-limit', `time-stamp-start', or 156The end text normally starts on the same line as the start text ends,
157`time-stamp-end' for yourself or you will be incompatible 157but if there are any newlines in `time-stamp-format', the same number
158of newlines must separate the start and end. \\[time-stamp] tries
159to not change the number of lines in the buffer. `time-stamp-inserts-lines'
160controls this behavior.
161
162Do not change `time-stamp-line-limit', `time-stamp-start', `time-stamp-end',
163or `time-stamp-inserts-lines' for yourself or you will be incompatible
158with other people's files! If you must change them for some application, 164with other people's files! If you must change them for some application,
159do so in the local variables section of the time-stamped file itself.") 165do so in the local variables section of the time-stamped file itself.")
160 166
161 167
168(defvar time-stamp-inserts-lines nil ;Do not change!
169 "Whether time-stamp can change the number of lines in a file.
170If nil, \\[time-stamp] skips as many lines as there are newlines in
171`time-stamp-format' before looking for the `time-stamp-end' pattern,
172thus it tries not to change the number of lines in the buffer.
173If non-nil, \\[time-stamp] starts looking for the end pattern
174immediately after the start pattern. This behavior can cause
175unexpected changes in the buffer if used carelessly, but it is useful
176for generating repeated time stamps.
177
178Do not change `time-stamp-end' or `time-stamp-inserts-lines' for
179yourself or you will be incompatible with other people's files!
180If you must change them for some application, do so in the local
181variables section of the time-stamped file itself.")
182
183
184(defvar time-stamp-count 1 ;Do not change!
185 "How many time stamp templates \\[time-stamp] will look for in a buffer.
186The same time-stamp will be written in each case.
187
188Do not change `time-stamp-count' for yourself or you will be
189incompatible with other people's files! If you must change it for
190some application, do so in the local variables section of the
191time-stamped file itself.")
192
193
162(defvar time-stamp-pattern "%%" ;Do not change! 194(defvar time-stamp-pattern "%%" ;Do not change!
163 "Convenience variable setting all time-stamp location and format variables. 195 "Convenience variable setting all `time-stamp' location and format values.
164This string has four parts, each of which is optional. 196This string has four parts, each of which is optional.
165These four parts set time-stamp-line-limit, time-stamp-start, 197These four parts set `time-stamp-line-limit', `time-stamp-start',
166time-stamp-format, and time-stamp-end. See the documentation 198`time-stamp-format', and `time-stamp-end'. See the documentation
167for each of these variables for details. 199for each of these variables for details.
168 200
169The first part is a number followed by a slash; the number sets the number 201The first part is a number followed by a slash; the number sets the number
@@ -175,7 +207,7 @@ The second part is a regexp identifying the pattern preceding the time stamp.
175This part may be omitted to use the normal pattern. 207This part may be omitted to use the normal pattern.
176 208
177The third part specifies the format of the time-stamp inserted. See 209The third part specifies the format of the time-stamp inserted. See
178the documentation for time-stamp-format for details. Specify this 210the documentation for `time-stamp-format' for details. Specify this
179part as \"%%\" to use the normal format. 211part as \"%%\" to use the normal format.
180 212
181The fourth part is a regexp identifying the pattern following the time stamp. 213The fourth part is a regexp identifying the pattern following the time stamp.
@@ -192,7 +224,7 @@ of the time-stamped file itself.")
192 224
193;;;###autoload 225;;;###autoload
194(defun time-stamp () 226(defun time-stamp ()
195 "Update the time stamp string in the buffer. 227 "Update the time stamp string(s) in the buffer.
196A template in a file can be automatically updated with a new time stamp 228A template in a file can be automatically updated with a new time stamp
197every time you save the file. Add this line to your .emacs file: 229every time you save the file. Add this line to your .emacs file:
198 (add-hook 'write-file-hooks 'time-stamp) 230 (add-hook 'write-file-hooks 'time-stamp)
@@ -204,17 +236,19 @@ The time stamp is written between the brackets or quotes:
204 Time-stamp: <1998-02-18 10:20:51 gildea> 236 Time-stamp: <1998-02-18 10:20:51 gildea>
205The time stamp is updated only if the variable `time-stamp-active' is non-nil. 237The time stamp is updated only if the variable `time-stamp-active' is non-nil.
206The format of the time stamp is set by the variable `time-stamp-format'. 238The format of the time stamp is set by the variable `time-stamp-format'.
207The variables `time-stamp-line-limit', `time-stamp-start', 239The variables `time-stamp-line-limit', `time-stamp-start', `time-stamp-end',
208and `time-stamp-end' control finding the template." 240`time-stamp-count', and `time-stamp-inserts-lines' control finding the
241template."
209 (interactive) 242 (interactive)
210 (let ((case-fold-search nil) 243 (let ((line-limit time-stamp-line-limit)
211 (start nil)
212 (end nil)
213 search-limit
214 (line-limit time-stamp-line-limit)
215 (ts-start time-stamp-start) 244 (ts-start time-stamp-start)
216 (ts-format time-stamp-format) 245 (ts-format time-stamp-format)
217 (ts-end time-stamp-end)) 246 (ts-end time-stamp-end)
247 (ts-count time-stamp-count)
248 (format-lines 0)
249 (end-lines 1)
250 (start nil)
251 search-limit)
218 (if (stringp time-stamp-pattern) 252 (if (stringp time-stamp-pattern)
219 (progn 253 (progn
220 (string-match "\\`\\(\\(-?[0-9]+\\)/\\)?\\([^%]+\\)?\\(\\(.\\|\n\\)*%[-.,:@+_ #^()0-9]*[A-Za-z%]\\)?\\([^%]+\\)?\\'" time-stamp-pattern) 254 (string-match "\\`\\(\\(-?[0-9]+\\)/\\)?\\([^%]+\\)?\\(\\(.\\|\n\\)*%[-.,:@+_ #^()0-9]*[A-Za-z%]\\)?\\([^%]+\\)?\\'" time-stamp-pattern)
@@ -232,6 +266,22 @@ and `time-stamp-end' control finding the template."
232 (setq line-limit 8) 266 (setq line-limit 8)
233 (message "time-stamp-line-limit is not an integer") 267 (message "time-stamp-line-limit is not an integer")
234 (sit-for 1))) 268 (sit-for 1)))
269 (cond ((not (integerp ts-count))
270 (setq ts-count 1)
271 (message "time-stamp-count is not an integer")
272 (sit-for 1))
273 ((< ts-count 1)
274 ;; We need to call time-stamp-once at least once
275 ;; to output any warnings about time-stamp not being active.
276 (setq ts-count 1)))
277 ;; Figure out what lines the end should be on.
278 (let ((nl-start 0))
279 (while (string-match "\n" ts-format nl-start)
280 (setq format-lines (1+ format-lines) nl-start (match-end 0))))
281 (let ((nl-start 0))
282 (while (string-match "\n" ts-end nl-start)
283 (setq end-lines (1+ end-lines) nl-start (match-end 0))))
284 ;; Find overall what lines to look at
235 (save-excursion 285 (save-excursion
236 (save-restriction 286 (save-restriction
237 (widen) 287 (widen)
@@ -245,17 +295,46 @@ and `time-stamp-end' control finding the template."
245 (setq start (point))) 295 (setq start (point)))
246 (t ;0 => no limit (use with care!) 296 (t ;0 => no limit (use with care!)
247 (setq start (point-min)) 297 (setq start (point-min))
248 (setq search-limit (point-max)))) 298 (setq search-limit (point-max))))))
249 (goto-char start) 299 (while (and start
250 (while (and (< (point) search-limit) 300 (< start search-limit)
301 (> ts-count 0))
302 (setq start (time-stamp-once start search-limit ts-start ts-end
303 ts-format format-lines end-lines))
304 (setq ts-count (1- ts-count))))
305 ;; be sure to return nil so can be used on write-file-hooks
306 nil)
307
308(defun time-stamp-once (start search-limit ts-start ts-end
309 ts-format format-lines end-lines)
310 "Update one time-stamp. Internal routine called by \\[time-stamp].
311Returns the end point, which is where `time-stamp' begins the next search."
312 (let ((case-fold-search nil)
313 (end nil)
314 end-search-start
315 (end-length nil))
316 (save-excursion
317 (save-restriction
318 (widen)
319 ;; Find the location of the time stamp.
320 (while (and (< (goto-char start) search-limit)
251 (not end) 321 (not end)
252 (re-search-forward ts-start search-limit 'move)) 322 (re-search-forward ts-start search-limit 'move))
253 (setq start (point)) 323 (setq start (point))
254 (end-of-line) 324 (if (not time-stamp-inserts-lines)
255 (let ((line-end (point))) 325 (forward-line format-lines))
256 (goto-char start) 326 (setq end-search-start (max start (point)))
257 (if (re-search-forward ts-end line-end 'move) 327 (if (= (forward-line end-lines) 0)
258 (setq end (match-beginning 0))))))) 328 (progn
329 (and (bolp) (backward-char))
330 (let ((line-end (min (point) search-limit)))
331 (if (>= line-end end-search-start)
332 (progn
333 (goto-char end-search-start)
334 (if (re-search-forward ts-end line-end t)
335 (progn
336 (setq end (match-beginning 0))
337 (setq end-length (- (match-end 0) end))))))))))))
259 (if end 338 (if end
260 (progn 339 (progn
261 ;; do all warnings outside save-excursion 340 ;; do all warnings outside save-excursion
@@ -283,11 +362,14 @@ and `time-stamp-end' control finding the template."
283 (insert-and-inherit new-time-stamp) 362 (insert-and-inherit new-time-stamp)
284 (setq end (point)) 363 (setq end (point))
285 ;; remove any tabs used to format time stamp 364 ;; remove any tabs used to format time stamp
286 (goto-char start) 365 (if (search-backward "\t" start t)
287 (if (search-forward "\t" end t) 366 (progn
288 (untabify start end))))))))))) 367 (untabify start end)
289 ;; be sure to return nil so can be used on write-file-hooks 368 (setq end (point))))))))))))
290 nil) 369 ;; return the location after this time stamp, if there was one
370 (and end end-length
371 (+ end end-length))))
372
291 373
292;;;###autoload 374;;;###autoload
293(defun time-stamp-toggle-active (&optional arg) 375(defun time-stamp-toggle-active (&optional arg)
@@ -298,7 +380,37 @@ With arg, turn time stamping on if and only if arg is positive."
298 (if (null arg) 380 (if (null arg)
299 (not time-stamp-active) 381 (not time-stamp-active)
300 (> (prefix-numeric-value arg) 0))) 382 (> (prefix-numeric-value arg) 0)))
301 (message "time-stamp is now %s." (if time-stamp-active "active" "off"))) 383 (message "time-stamp is now %s." (if time-stamp-active "active" "off")))
384
385
386(defun time-stamp-string (&optional ts-format)
387 "Generate the new string to be inserted by \\[time-stamp].
388Optionally use FORMAT."
389 (or ts-format
390 (setq ts-format time-stamp-format))
391 (if (stringp ts-format)
392 (if (stringp time-stamp-time-zone)
393 (let ((ts-real-time-zone (getenv "TZ")))
394 (unwind-protect
395 (progn
396 (setenv "TZ" time-stamp-time-zone)
397 (format-time-string
398 (time-stamp-string-preprocess ts-format)))
399 (setenv "TZ" ts-real-time-zone)))
400 (format-time-string
401 (time-stamp-string-preprocess ts-format)))
402 ;; handle version 1 compatibility
403 (cond ((or (eq time-stamp-old-format-warn 'error)
404 (and (eq time-stamp-old-format-warn 'ask)
405 (not (y-or-n-p "Use non-string time-stamp-format? "))))
406 (message "Warning: no time-stamp: time-stamp-format not a string")
407 (sit-for 1)
408 nil)
409 (t
410 (cond ((eq time-stamp-old-format-warn 'warn)
411 (message "Obsolescent time-stamp-format type; should be string")
412 (sit-for 1)))
413 (time-stamp-fconcat ts-format " ")))))
302 414
303(defconst time-stamp-no-file "(no file)" 415(defconst time-stamp-no-file "(no file)"
304 "String to use when the buffer is not associated with a file.") 416 "String to use when the buffer is not associated with a file.")
@@ -316,7 +428,7 @@ With arg, turn time stamping on if and only if arg is positive."
316;;; The : modifier is a temporary conversion feature used to resolve 428;;; The : modifier is a temporary conversion feature used to resolve
317;;; ambiguous formats--formats that are changing (over time) incompatibly. 429;;; ambiguous formats--formats that are changing (over time) incompatibly.
318(defun time-stamp-string-preprocess (format &optional time) 430(defun time-stamp-string-preprocess (format &optional time)
319 ;; Uses a FORMAT to format date, time, file, and user information. 431 ;; Use a FORMAT to format date, time, file, and user information.
320 ;; Optional second argument TIME is only for testing. 432 ;; Optional second argument TIME is only for testing.
321 ;; Implements non-time extensions to format-time-string 433 ;; Implements non-time extensions to format-time-string
322 ;; and all time-stamp-format compatibility. 434 ;; and all time-stamp-format compatibility.
@@ -377,7 +489,7 @@ With arg, turn time stamping on if and only if arg is positive."
377 (setq field-result 489 (setq field-result
378 (cond 490 (cond
379 ((eq cur-char ?%) 491 ((eq cur-char ?%)
380 "%") 492 "%%")
381 ((eq cur-char ?a) ;day of week 493 ((eq cur-char ?a) ;day of week
382 (if change-case 494 (if change-case
383 (format-time-string "%#A" time) 495 (format-time-string "%#A" time)
@@ -453,6 +565,10 @@ With arg, turn time stamping on if and only if arg is positive."
453 (user-login-name)) 565 (user-login-name))
454 ((eq cur-char ?U) ;user full name 566 ((eq cur-char ?U) ;user full name
455 (user-full-name)) 567 (user-full-name))
568 ((eq cur-char ?l) ;logname (undocumented user name alt)
569 (user-login-name))
570 ((eq cur-char ?L) ;(undocumented alt user full name)
571 (user-full-name))
456 ((eq cur-char ?h) ;mail host name 572 ((eq cur-char ?h) ;mail host name
457 (time-stamp-mail-host-name)) 573 (time-stamp-mail-host-name))
458 )) 574 ))
@@ -492,13 +608,13 @@ With arg, turn time stamping on if and only if arg is positive."
492 (string-to-int (format-time-string format-string time))))) 608 (string-to-int (format-time-string format-string time)))))
493 609
494(defvar time-stamp-conversion-warn t 610(defvar time-stamp-conversion-warn t
495 "Non-nil to warn about soon-to-be-unsupported forms in time-stamp-format. 611 "Non-nil to warn about soon-to-be-unsupported forms in `time-stamp-format'.
496In would be a bad idea to disable these warnings! 612In would be a bad idea to disable these warnings!
497You really need to update your files instead. 613You really need to update your files instead.
498 614
499The new formats will work with old versions of Emacs. 615The new formats will work with old versions of Emacs.
500New formats are being recommended now to allow time-stamp-format 616New formats are being recommended now to allow `time-stamp-format'
501to change in the future to be compatible with format-time-string. 617to change in the future to be compatible with `format-time-string'.
502The new forms being recommended now will continue to work then.") 618The new forms being recommended now will continue to work then.")
503 619
504 620
@@ -520,42 +636,10 @@ The new forms being recommended now will continue to work then.")
520 636
521 637
522 638
523(defun time-stamp-string (&optional ts-format)
524 "Generate the new string to be inserted by \\[time-stamp].
525Optionally use FORMAT."
526 (or ts-format
527 (setq ts-format time-stamp-format))
528 (if (stringp ts-format)
529 (if (stringp time-stamp-time-zone)
530 (let ((real-time-zone (getenv "TZ")))
531 (unwind-protect
532 (progn
533 (setenv "TZ" time-stamp-time-zone)
534 (format-time-string
535 (time-stamp-string-preprocess ts-format)))
536 (setenv "TZ" real-time-zone)))
537 (format-time-string
538 (time-stamp-string-preprocess ts-format)))
539 ;; handle version 1 compatibility
540 (cond ((or (eq time-stamp-old-format-warn 'error)
541 (and (eq time-stamp-old-format-warn 'ask)
542 (not (y-or-n-p "Use non-string time-stamp-format? "))))
543 (message "Warning: no time-stamp: time-stamp-format not a string")
544 (sit-for 1)
545 nil)
546 (t
547 (cond ((eq time-stamp-old-format-warn 'warn)
548 (message "Obsolescent time-stamp-format type; should be string")
549 (sit-for 1)))
550 (time-stamp-fconcat ts-format " ")))))
551
552(defconst time-stamp-no-file "(no file)"
553 "String to use when the buffer is not associated with a file.")
554
555(defun time-stamp-mail-host-name () 639(defun time-stamp-mail-host-name ()
556 "Return the name of the host where the user receives mail. 640 "Return the name of the host where the user receives mail.
557This is the value of `mail-host-address' if bound and a string, 641This is the value of `mail-host-address' if bound and a string,
558otherwise the value of the function system-name." 642otherwise the value of the function `system-name'."
559 (or (and (boundp 'mail-host-address) 643 (or (and (boundp 'mail-host-address)
560 (stringp mail-host-address) 644 (stringp mail-host-address)
561 mail-host-address) 645 mail-host-address)