Backport expansion of Time Stamp documentation

* doc/emacs/files.texi (Time Stamps): Add examples of enabling
time stamping with add-hook, setting time-stamp-pattern as a
file-local variable, and showing a time stamp at the end of a
file.  Divide into three sections.
* doc/emacs/emacs.texi: Add new nodes to menu.
* lisp/info.el (Info-file-list-for-emacs): Remove entry that
points Info at time-stamp discussion in the Autotype document.
* lisp/time-stamp.el (time-stamp-format, time-stamp-active,
time-stamp-count, time-stamp-pattern, time-stamp, time-stamp-string):
Expand doc strings.  Include Info cross-references.

Cherry picked from commits on the main branch.
Do not merge to master.
This commit is contained in:
Stephen Gildea 2025-03-30 11:39:53 -07:00
parent 38fec86281
commit 43c9eb3df6
4 changed files with 186 additions and 51 deletions

View file

@ -486,6 +486,11 @@ Backup Files
* Backup Deletion:: Emacs deletes excess numbered backups.
* Backup Copying:: Backups can be made by copying or renaming.
Updating Time Stamps Automatically
* Time Stamp Customization:: How to customize with time-stamp-pattern.
* Time Stamps for One File:: Ensure automatic time-stamp of a specific file.
@ifnottex
Auto Reverting Non-File Buffers

View file

@ -411,7 +411,7 @@ that was visited in the buffer.
* Interlocking:: How Emacs protects against simultaneous editing
of one file by two users.
* Shadowing: File Shadowing. Copying files to ``shadows'' automatically.
* Time Stamps:: Emacs can update time stamps on saved files.
* Time Stamps:: Emacs can update time stamps when a file is saved.
@end menu
@node Save Commands
@ -992,35 +992,152 @@ File Shadowing is not available on MS Windows.
@node Time Stamps
@subsection Updating Time Stamps Automatically
@cindex time stamps
@cindex time stamps, automatic file timestamps
@cindex modification dates
@cindex locale, date format
@cindex last modified time
You can arrange to put a time stamp in a file, so that it is updated
automatically each time you edit and save the file. The time stamp
must be in the first eight lines of the file, and you should insert it
like this:
You can arrange to have a time stamp in a file be updated
automatically each time you save the file.
(A time stamp may also be called a date stamp or a last modified time.)
Having a time stamp in the text of a file ensures that the time the file
was written will be preserved even if the file is copied or transformed
in a way that loses the file system's modification time.
There are two steps to setting up automatic time stamping.
First, the file needs a time stamp template
somewhere in the first eight lines.
The template looks like this:
@example
Time-stamp: <>
@end example
@noindent
or like this:
or (your choice) like this:
@example
Time-stamp: " "
@end example
@findex time-stamp
Then add the function @code{time-stamp} to the hook
@code{before-save-hook} (@pxref{Hooks}). When you save the file, this
function then automatically updates the time stamp with the current
date and time. You can also use the command @kbd{M-x time-stamp} to
update the time stamp manually. By default the time stamp is
With that template in place, you can update the current buffer's time
stamp once immediately with the command @kbd{M-x time-stamp}.
Emacs will check for a template; if a template is found,
Emacs will write the current date, time, author, and/or
other info between the brackets or quotes.
(If the buffer has no template, @code{time-stamp} does nothing.)
After the first time stamp, the line might look like this:
@example
Time-stamp: <1993-07-06 11:05:14 terryg>
@end example
Second, configure Emacs to run @code{time-stamp} any time it saves a
file, by adding @code{time-stamp}
to @code{before-save-hook} (@pxref{Hooks}).
You can either customize the option @code{before-save-hook}
(with @kbd{M-x customize-option}, @pxref{Specific Customization}),
or you can edit your init file adding this line:
@example
(add-hook 'before-save-hook 'time-stamp)
@end example
@menu
* Time Stamp Customization:: How to customize with time-stamp-pattern.
* Time Stamps for One File:: Ensure automatic time-stamp of a specific file.
@end menu
@node Time Stamp Customization
@subsubsection Customizing the Time Stamp
@vindex time-stamp-pattern
To customize the time stamp in a particular file, set the
variable @code{time-stamp-pattern} in that file's local variables
list (@pxref{Specifying File Variables}).
You can change what pattern @code{time-stamp} will match against to
identify a template and where in the file to look for the pattern using
@code{time-stamp-pattern}; for details, see the variable's built-in
documentation (with @kbd{C-h v}, @pxref{Name Help}).
As a simple example, if this line occurs near the top of a file:
@example
publishing_year_and_city = "Published nnnn in Boston, Mass.";
@end example
@noindent
then the following comment at the end of the same file tells
@code{time-stamp} how to identify and update that custom template:
@example
@group
// Local variables:
// time-stamp-pattern: "Published %Y in Boston"
// End:
@end group
@end example
This pattern says that the text before the start of the time stamp is
``Published '', and the text after the end is `` in Boston''.
If @code{time-stamp} finds both in one of the first eight lines,
what is between will be replaced by the current year, as requested by
the @code{%Y} format.
After any change to file-local variables,
type @kbd{M-x normal-mode} to re-read them.
Here is another example, with the time stamp inserted into
the last paragraph of an HTML document.
Since this template is at the end of the document, not in the first
eight lines, @code{time-stamp-format} starts with @code{-10/} to tell
@code{time-stamp} to look at the last 10 lines.
The @code{%%} asks for the default format
(specified by @code{time-stamp-format}).
@example
@r{@dots{}}
<p>Last modified: </p>
</body>
</html>
<!--
Local variables:
time-stamp-pattern: "-10/Last modified: %%</p>$"
End:
-->
@end example
@vindex time-stamp-format
By default the time stamp is
formatted according to your locale setting (@pxref{Environment}) and
time zone (@pxref{Time of Day,,, elisp, The Emacs Lisp Reference
Manual}). For customizations, see the Custom group @code{time-stamp}.
Manual}).
See the built-in documentation for the variable @code{time-stamp-format}
for specifics and other variables that affect the formatting.
@node Time Stamps for One File
@subsubsection Forcing Time Stamps for One File
If you are working on a file with multiple authors, and you cannot
be sure the other authors have enabled time-stamping globally in
their Emacs init files, you can force it to be enabled for a
particular file by adding @code{time-stamp} to that buffer's
@code{before-save-hook} in that file's local variables list.
To extend one of the previous examples:
@example
@group
// Local variables:
// eval: (add-hook 'before-save-hook 'time-stamp nil t)
// time-stamp-pattern: "Published %Y in Boston"
// End:
@end group
@end example
@noindent
Although this example shows them both set together,
you can use @code{eval} without also setting @code{time-stamp-pattern}
if you like the default pattern.
@node Reverting
@section Reverting a Buffer

View file

@ -4666,7 +4666,6 @@ Advanced commands:
("java" . "ccmode") ("idl" . "ccmode") ("pike" . "ccmode")
("skeleton" . "autotype") ("auto-insert" . "autotype")
("copyright" . "autotype") ("executable" . "autotype")
("time-stamp" . "autotype")
("tempo" . "autotype") ("hippie-expand" . "autotype")
("cvs" . "pcl-cvs") ("ada" . "ada-mode") "calc"
("calcAlg" . "calc") ("calcDigit" . "calc") ("calcVar" . "calc")

View file

@ -31,8 +31,8 @@
;; (add-hook 'before-save-hook 'time-stamp)
;; Now any time-stamp templates in your files will be updated automatically.
;; See the documentation for the functions `time-stamp'
;; and `time-stamp-toggle-active' for details.
;; For details, see the documentation for function `time-stamp'
;; and the Info node `Time Stamps'.
;;; Code:
@ -64,7 +64,7 @@ with %, as follows.
%5z time zone offset: `-0500' (since Emacs 27; see note below)
Non-date items:
%% a literal percent character: `%'
%% literal percent character: \"%\"
%f file name without directory %F absolute file name
%l login name %L full name of logged-in user
%q unqualified host name %Q fully-qualified host name
@ -74,12 +74,12 @@ Decimal digits between the % and the type character specify the
field width. Strings are truncated on the right.
A leading zero in the field width zero-fills a number.
For example, to get the format used by the `date' command,
For example, to get a common format used by the \"date\" command,
use \"%3a %3b %2d %02H:%02M:%02S %Z %Y\".
The values of non-numeric formatted items depend on the locale
setting recorded in `system-time-locale' and `locale-coding-system'.
The examples here are for the default (`C') locale.
The examples here are for the default (\"C\") locale.
`time-stamp-time-zone' controls the time zone used.
The default padding of some formats has changed to be more compatible
@ -95,7 +95,7 @@ edited by older versions of Emacs also, do not use this format yet."
(defcustom time-stamp-active t
"Non-nil to enable time-stamping of buffers by \\[time-stamp].
"Non-nil enables time-stamping of buffers by \\[time-stamp].
Can be toggled by \\[time-stamp-toggle-active].
This option does not affect when `time-stamp' is run, only what it
@ -229,7 +229,11 @@ your init file, you would be incompatible with other people's files.")
(defvar time-stamp-count 1 ;Do not change!
"How many templates \\[time-stamp] will look for in a buffer.
The same time stamp will be written in each case.
If the value is greater than 1, the same time stamp will be written in
each case. If you want to insert different text on different lines,
then instead of changing this variable, include a newline (written as
\"\\n\") in `time-stamp-format' or the format part of `time-stamp-pattern'.
`time-stamp-count' is best changed with a file-local variable.
If you were to change it in your init file, you would be incompatible
@ -240,55 +244,61 @@ with other people's files.")
(defvar time-stamp-pattern nil ;Do not change!
"Convenience variable setting all `time-stamp' location and format values.
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.
These four parts override `time-stamp-line-limit', `time-stamp-start',
`time-stamp-format' and `time-stamp-end', respectively. 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.
value of `time-stamp-line-limit' as the number.
The second part is a regexp identifying the pattern preceding the time stamp.
This part may be omitted to use the normal pattern.
This part may be omitted to use the value of `time-stamp-start'.
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 third part specifies the format of the time stamp inserted. Specify
this part as \"%%\" to use the value of `time-stamp-format'.
The fourth part is a regexp identifying the pattern following the time stamp.
This part may be omitted to use the normal pattern.
This part may be omitted to use the value of `time-stamp-end'.
The pattern does not need to match the entire line of the time stamp.
The pattern will update time stamp information on multiple lines if the
pattern includes newlines, which can be written as \"\\n\".
These variables are best changed with file-local variables.
If you were to change `time-stamp-pattern', `time-stamp-line-limit',
`time-stamp-start', or `time-stamp-end' in your init file, you
would be incompatible with other people's files.
See also `time-stamp-count' and `time-stamp-inserts-lines'.
Examples:
\"-10/\" (sets only `time-stamp-line-limit')
;; time-stamp-pattern: \"-10/\"
(sets only `time-stamp-line-limit')
\"-9/^Last modified: %%$\" (sets `time-stamp-line-limit',
`time-stamp-start' and `time-stamp-end')
// time-stamp-pattern: \"-9/^Last modified: %%$\"
(sets `time-stamp-line-limit', `time-stamp-start' and `time-stamp-end')
\"@set Time-stamp: %:B %1d, %Y$\" (sets `time-stamp-start',
`time-stamp-format' and `time-stamp-end')
@c time-stamp-pattern: \"@set Time-stamp: %:B %1d, %Y$\"
(sets `time-stamp-start', `time-stamp-format' and `time-stamp-end')
\"newcommand{\\\\\\\\timestamp}{%%}\" (sets `time-stamp-start'
and `time-stamp-end')")
%% time-stamp-pattern: \"newcommand{\\\\\\\\timestamp}{%%}\"
(sets `time-stamp-start' and `time-stamp-end')
See Info node `Time Stamp Customization' for more discussion and more
in-depth examples.
See also `time-stamp-count' and `time-stamp-inserts-lines'.")
;;;###autoload(put 'time-stamp-pattern 'safe-local-variable 'stringp)
;;;###autoload
(defun time-stamp ()
"Update any time stamp string(s) in the buffer.
This function looks for a time stamp template and updates it with
the current date, time, and/or other info.
"Update any time stamp strings (timestamps) in the buffer.
Look for a time stamp template and update it with the current
date, time, author, and/or other info.
The template, which you manually create on one of the first 8 lines
of the file before running this function, by default can look like
@ -311,12 +321,11 @@ To enable automatic time-stamping for only a specific file, add
this line to a local variables list near the end of the file:
eval: (add-hook \\='before-save-hook \\='time-stamp nil t)
If the file has no time-stamp template, this function does nothing.
If the file has no time stamp template or if `time-stamp-active' is nil,
this function does nothing.
You can set `time-stamp-pattern' in a file's local variables list
to customize the information in the time stamp and where it is written.
The time stamp is updated only if `time-stamp-active' is non-nil."
to customize the information in the time stamp and where it is written."
(interactive)
(let ((line-limit time-stamp-line-limit)
(ts-start time-stamp-start)
@ -466,10 +475,15 @@ Internal helper used by `time-stamp-string-preprocess'."
(format-time-string format time time-stamp-time-zone))
(defun time-stamp-string (&optional ts-format time)
"Generate the new string to be inserted by \\[time-stamp].
Optionally use format TS-FORMAT instead of `time-stamp-format' to
format the string. Optional second argument TIME is only for testing;
normally the current time is used."
"Return the current time and other info formatted for \\[time-stamp].
Optional first argument TS-FORMAT gives the format to use; it defaults
to the value of `time-stamp-format'. Thus, with no arguments,
this function returns the string `time-stamp' would use to update
its template in the buffer. The format accepted is similar to the
format used by `format-time-string' with some extensions; see the
documentation of `time-stamp-format' for details.
Optional second argument TIME is only for testing; normally the current
time is used. The time zone is determined by `time-stamp-time-zone'."
(if (stringp (or ts-format (setq ts-format time-stamp-format)))
(time-stamp-string-preprocess ts-format time)))