From 43c9eb3df6050f19211e219c7cb03da7a6d9d6dd Mon Sep 17 00:00:00 2001 From: Stephen Gildea Date: Sun, 30 Mar 2025 11:39:53 -0700 Subject: [PATCH 1/2] 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. --- doc/emacs/emacs.texi | 5 ++ doc/emacs/files.texi | 145 ++++++++++++++++++++++++++++++++++++++----- lisp/info.el | 1 - lisp/time-stamp.el | 86 ++++++++++++++----------- 4 files changed, 186 insertions(+), 51 deletions(-) diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index a81c7134a70..d8ca41d737e 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -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 diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index c04ac685ee0..2a7017779f6 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -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{}} +

Last modified:

+ + + +@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 diff --git a/lisp/info.el b/lisp/info.el index b484afc08cc..4aafe223549 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -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") diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 45de5a185e1..eb438ce3e52 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -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))) From 6cac92928a99a2cf33aeeeddf295cf981750391c Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Mon, 17 Feb 2025 15:21:16 +0000 Subject: [PATCH 2/2] Fix compilation errors due to insufficient compiler safety (bug#63288) The default safety level is 1. Restoring the default safety level to 1 after it was temporarily 0 should reset byte-compile-delete-errors to nil, its default level. Failing to do that resulted in miscompilation of code in highly-parallel builds. * lisp/emacs-lisp/cl-macs.el (cl--do-proclaim): Change 'byte-compile-delete-errors' to become t only at 'safety' level 0, not levels 1 or 2. (cherry picked from commit 53a5dada413662389a17c551a00d215e51f5049f) --- lisp/emacs-lisp/cl-macs.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 8caf2f1eac0..2a0a9e5c6de 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2670,7 +2670,7 @@ Example: (let ((speed (assq (nth 1 (assq 'speed (cdr spec))) '((0 nil) (1 t) (2 t) (3 t)))) (safety (assq (nth 1 (assq 'safety (cdr spec))) - '((0 t) (1 t) (2 t) (3 nil))))) + '((0 t) (1 nil) (2 nil) (3 nil))))) (if speed (setq cl--optimize-speed (car speed) byte-optimize (nth 1 speed))) (if safety (setq cl--optimize-safety (car safety)