aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1997-06-08 21:43:08 +0000
committerRichard M. Stallman1997-06-08 21:43:08 +0000
commitfd72ddf609b417abf526ccc8865631f813e066e1 (patch)
treef02433fdddc5cedf57b86ef8c7aaa927c3d0af0a
parente9f527a0ce960ebd79eb30fc56b349464a156572 (diff)
downloademacs-fd72ddf609b417abf526ccc8865631f813e066e1.tar.gz
emacs-fd72ddf609b417abf526ccc8865631f813e066e1.zip
(time-stamp-format): Doc fix. Use %;y.
(time-stamp-string-preprocess): Don't just call format-time-string; handle compatibility for some old constructs. Handle padding the historical way, while giving a warning if people actually depend on it. (time-stamp-conv-warn, time-stamp-conversion-warn) (time-stamp-do-number): New functions.
-rw-r--r--lisp/time-stamp.el289
1 files changed, 249 insertions, 40 deletions
diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el
index 0944a73d611..f357ddc7068 100644
--- a/lisp/time-stamp.el
+++ b/lisp/time-stamp.el
@@ -1,8 +1,8 @@
1;;; time-stamp.el --- Maintain last change time stamps in files edited by Emacs 1;;; time-stamp.el --- Maintain last change time stamps in files edited by Emacs
2 2
3;; Copyright 1989, 1993, 1994, 1995 Free Software Foundation, Inc. 3;; Copyright 1989, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
4 4
5;; Maintainer's Time-stamp: <1997-04-28 11:51:22 gildea> 5;; Maintainer's Time-stamp: <1997-06-01 17:02:45 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
@@ -66,23 +66,47 @@ If nil, no notification is given."
66 (const ask) (const warn)) 66 (const ask) (const warn))
67 :group 'time-stamp) 67 :group 'time-stamp)
68 68
69(defcustom time-stamp-format "%Y-%02m-%02d %02H:%02M:%02S %u" 69(defcustom time-stamp-format "%:y-%02m-%02d %02H:%02M:%02S %u"
70 "*Format of the string inserted by \\[time-stamp]. 70 "*Format of the string inserted by \\[time-stamp].
71The value may be a string or a list. Lists are supported only for 71The value may be a string or a list. Lists are supported only for
72backward compatibility; see variable `time-stamp-old-format-warn'. 72backward compatibility; see variable `time-stamp-old-format-warn'.
73 73
74A string is used with `format-time-string'. 74A string is used verbatim except for character sequences beginning with %:
75In addition to the features of `format-time-string', 75
76you can use the following %-constructs: 76%:a weekday name: `Monday'. %#A gives uppercase: `MONDAY'
77 77%3a abbreviated weekday: `Mon'. %3A gives uppercase: `MON'
78%f file name without directory 78%:b month name: `January'. %#B gives uppercase: `JANUARY'
79%F full file name 79%3b abbreviated month: `Jan'. %3B gives uppercase: `JAN'
80%h mail host name 80%02d day of month
81%s system name 81%02H 24-hour clock hour
82%u user's login name 82%02I 12-hour clock hour
83%02m month number
84%02M minute
85%#p `am' or `pm'. %P gives uppercase: `AM' or `PM'
86%02S seconds
87%w day number of week, Sunday is 0
88%02y 2-digit year: `97' %:y 4-digit year: `1997'
89%z time zone name: `est'. %Z gives uppercase: `EST'
90
91Non-date items:
92%% a literal percent character: `%'
93%f file name without directory %F gives absolute pathname
94%s system name
95%u user's login name
96%h mail host name
97
98Decimal digits between the % and the type character specify the
99field width. Strings are truncated on the right; years on the left.
100A leading zero causes numbers to be zero-filled.
83 101
84For example, to get the format used by the `date' command, 102For example, to get the format used by the `date' command,
85use \"%3a %3b %2d %02H:%02M:%02S %Z %Y\"." 103use \"%3a %3b %2d %02H:%02M:%02S %Z %:y\".
104
105In the future these formats will be aligned more with format-time-string.
106Because of this transition, the default padding for numeric formats will
107change in a future version. Therefore either a padding width should be
108specified, or the : modifier should be used to explicitly request the
109historical default."
86 :type 'string 110 :type 'string
87 :group 'time-stamp) 111 :group 'time-stamp)
88 112
@@ -221,33 +245,218 @@ With arg, turn time stamping on if and only if arg is positive."
221(defconst time-stamp-no-file "(no file)" 245(defconst time-stamp-no-file "(no file)"
222 "String to use when the buffer is not associated with a file.") 246 "String to use when the buffer is not associated with a file.")
223 247
224(defun time-stamp-string-preprocess (format) 248;;; time-stamp is transitioning to using the new, expanded capabilities
225 "Process occurrences in FORMAT of %f, %F, %h, %s and %u. 249;;; of format-time-string. During the process, this function implements
226These are replaced with the file name (nondirectory part), 250;;; intermediate, compatible formats and complains about old, soon to
227full file name, host name for mail, system name, and user name. 251;;; be unsupported, formats. This function will get a lot (a LOT) shorter
228Do not alter other %-combinations, and do detect %%." 252;;; when the transition is complete and we can just pass most things
229 (let ((result "") (pos 0) (case-fold-search nil)) 253;;; straight through to format-time-string.
230 (while (string-match "%[%uhfFs]" format pos) 254;;; At all times, all the formats recommended in the doc string
231 (setq result (concat result (substring format pos (match-beginning 0)))) 255;;; of time-stamp-format will work not only in the current version of
232 (let ((char (aref format (1+ (match-beginning 0))))) 256;;; Emacs, but in all versions that have been released within the past
233 (cond ((= char ?%) 257;;; two years.
234 (setq result (concat result "%%"))) 258;;; The : modifier is a temporary conversion feature used to resolve
235 ((= char ?u) 259;;; ambiguous formats--formats that are changing (over time) incompatibly.
236 (setq result (concat result (user-login-name)))) 260(defun time-stamp-string-preprocess (format &optional time)
237 ((= char ?f) 261 ;; Uses a FORMAT to format date, time, file, and user information.
238 (setq result (concat result 262 ;; Optional second argument TIME is only for testing.
239 (if buffer-file-name 263 ;; Implements non-time extensions to format-time-string
240 (file-name-nondirectory buffer-file-name) 264 ;; and all time-stamp-format compatibility.
241 time-stamp-no-file)))) 265 (let ((fmt-len (length format))
242 ((= char ?F) 266 (ind 0)
243 (setq result (concat result 267 cur-char
244 (or buffer-file-name time-stamp-no-file)))) 268 (prev-char nil)
245 ((= char ?s) 269 (result "")
246 (setq result (concat result (system-name)))) 270 field-index
247 ((= char ?h) 271 field-width
248 (setq result (concat result (time-stamp-mail-host-name)))))) 272 field-result
249 (setq pos (match-end 0))) 273 alt-form change-case require-padding
250 (concat result (substring format pos)))) 274 (paren-level 0))
275 (while (< ind fmt-len)
276 (setq cur-char (aref format ind))
277 (setq
278 result
279 (concat result
280 (cond
281 ((eq cur-char ?%)
282 ;; eat any additional args to allow for future expansion
283 (setq alt-form nil change-case nil require-padding nil)
284 (while (progn
285 (setq ind (1+ ind))
286 (setq cur-char (if (< ind fmt-len)
287 (aref format ind)
288 ?\0))
289 (or (eq ?. cur-char)
290 (eq ?, cur-char) (eq ?: cur-char) (eq ?@ cur-char)
291 (eq ?- cur-char) (eq ?+ cur-char) (eq ?_ cur-char)
292 (eq ?\ cur-char) (eq ?# cur-char) (eq ?^ cur-char)
293 (and (eq ?\( cur-char)
294 (not (eq prev-char ?\\))
295 (setq paren-level (1+ paren-level)))
296 (if (and (eq ?\) cur-char)
297 (not (eq prev-char ?\\))
298 (> paren-level 0))
299 (setq paren-level (1- paren-level))
300 (and (> paren-level 0)
301 (< ind fmt-len)))))
302 (setq prev-char cur-char)
303 ;; some characters we actually use
304 (cond ((eq cur-char ?:)
305 (setq alt-form t))
306 ((eq cur-char ?#)
307 (setq change-case t))))
308 ;; get format width
309 (setq field-index ind)
310 (setq ind (1- ind))
311 (while (progn
312 (setq ind (1+ ind))
313 (setq cur-char (if (< ind fmt-len)
314 (aref format ind)
315 ?\0))
316 (and (<= ?0 cur-char) (>= ?9 cur-char))))
317 (setq field-width (substring format field-index ind))
318 (setq field-result
319 (cond
320 ((eq cur-char ?%)
321 "%")
322 ((eq cur-char ?a) ;day of week
323 (if change-case
324 (format-time-string "%#A" time)
325 (or alt-form (not (string-equal field-width ""))
326 (time-stamp-conv-warn "%a" "%:a"))
327 (if (and alt-form (not (string-equal field-width "")))
328 "" ;discourage "%:3a"
329 (format-time-string "%A" time))))
330 ((eq cur-char ?A)
331 (if alt-form
332 (format-time-string "%A" time)
333 (or change-case (not (string-equal field-width ""))
334 (time-stamp-conv-warn "%A" "%#A"))
335 (format-time-string "%#A" time)))
336 ((eq cur-char ?b) ;month name
337 (if change-case
338 (format-time-string "%#B" time)
339 (or alt-form (not (string-equal field-width ""))
340 (time-stamp-conv-warn "%b" "%:b"))
341 (if (and alt-form (not (string-equal field-width "")))
342 "" ;discourage "%:3b"
343 (format-time-string "%B" time))))
344 ((eq cur-char ?B)
345 (if alt-form
346 (format-time-string "%B" time)
347 (or change-case (not (string-equal field-width ""))
348 (time-stamp-conv-warn "%B" "%#B"))
349 (format-time-string "%#B" time)))
350 ((eq cur-char ?d) ;day of month, 1-31
351 (time-stamp-do-number cur-char))
352 ((eq cur-char ?H) ;hour, 0-23
353 (time-stamp-do-number cur-char))
354 ((eq cur-char ?I) ;hour, 1-12
355 (time-stamp-do-number cur-char))
356 ((eq cur-char ?m) ;month number, 1-12
357 (time-stamp-do-number cur-char))
358 ((eq cur-char ?M) ;minute, 0-59
359 (time-stamp-do-number cur-char))
360 ((eq cur-char ?p) ;am or pm
361 (or change-case
362 (time-stamp-conv-warn "%p" "%#p"))
363 (format-time-string "%#p" time))
364 ((eq cur-char ?P) ;AM or PM
365 (format-time-string "%p" time))
366 ((eq cur-char ?S) ;seconds, 00-60
367 (time-stamp-do-number cur-char))
368 ((eq cur-char ?w) ;weekday number, Sunday is 0
369 (format-time-string "%w" time))
370 ((eq cur-char ?y) ;year
371 (or alt-form (not (string-equal field-width ""))
372 (time-stamp-conv-warn "%y" "%:y"))
373 (string-to-int (format-time-string "%Y" time)))
374 ((eq cur-char ?Y) ;4-digit year, new style
375 (string-to-int (format-time-string "%Y" time)))
376 ((eq cur-char ?z) ;time zone lower case
377 (if change-case
378 "" ;discourage %z variations
379 (format-time-string "%#Z" time)))
380 ((eq cur-char ?Z)
381 (if change-case
382 (format-time-string "%#Z" time)
383 (format-time-string "%Z" time)))
384 ((eq cur-char ?f) ;buffer-file-name, base name only
385 (if buffer-file-name
386 (file-name-nondirectory buffer-file-name)
387 time-stamp-no-file))
388 ((eq cur-char ?F) ;buffer-file-name, full path
389 (or buffer-file-name
390 time-stamp-no-file))
391 ((eq cur-char ?s) ;system name
392 (system-name))
393 ((eq cur-char ?u) ;user name
394 (user-login-name))
395 ((eq cur-char ?h) ;mail host name
396 (time-stamp-mail-host-name))
397 ))
398 (if (string-equal field-width "")
399 field-result
400 (let ((padded-result
401 (format (format "%%%s%c"
402 field-width
403 (if (numberp field-result) ?d ?s))
404 (or field-result ""))))
405 (let ((initial-length (length padded-result))
406 (desired-length (string-to-int field-width)))
407 (if (> initial-length desired-length)
408 ;; truncate strings on right, years on left
409 (if (stringp field-result)
410 (substring padded-result 0 desired-length)
411 (if (eq cur-char ?y)
412 (substring padded-result (- desired-length))
413 padded-result)) ;non-year numbers don't truncate
414 padded-result)))))
415 (t
416 (char-to-string cur-char)))))
417 (setq ind (1+ ind)))
418 result))
419
420(defun time-stamp-do-number (format-char)
421 ;; Handle compatible cases where only
422 ;; the default width/padding will change.
423 ;; Uses dynamic vars field-width, time.
424 (let ((format-string (concat "%" (char-to-string format-char))))
425 (and (not alt-form) (string-equal field-width "")
426 (time-stamp-conv-warn format-string
427 (format "%%:%c" format-char)))
428 (if (and alt-form (not (string-equal field-width "")))
429 "" ;discourage "%:2d" and the like
430 (string-to-int (format-time-string format-string time)))))
431
432(defvar time-stamp-conversion-warn t
433 "Non-nil to warn about soon-to-be-unsupported forms in time-stamp-format.
434In would be a bad idea to disable these warnings!
435You really need to update your files instead.
436
437The new formats will work with old versions of Emacs.
438New formats are being recommended now to allow time-stamp-format
439to change in the future to be compatible with format-time-string.
440The new forms being recommended now will continue to work then.")
441
442
443(defun time-stamp-conv-warn (old-form new-form)
444 ;; Display a warning about a soon-to-be-obsolete format.
445 (cond
446 (time-stamp-conversion-warn
447 (save-excursion
448 (set-buffer (get-buffer-create "*Time-stamp-compatibility*"))
449 (goto-char (point-max))
450 (if (bobp)
451 (progn
452 (insert
453 "The formats recognized in time-stamp-format will change in a future release\n"
454 "to be compatible with the new, expanded format-time-string function.\n\n"
455 "The following obsolescent time-stamp-format construct(s) were found:\n\n")))
456 (insert "\"" old-form "\" -- use " new-form "\n"))
457 (display-buffer "*Time-stamp-compatibility*"))))
458
459
251 460
252(defun time-stamp-string () 461(defun time-stamp-string ()
253 "Generate the new string to be inserted by \\[time-stamp]." 462 "Generate the new string to be inserted by \\[time-stamp]."