]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve file-has-changed-p
authorGregory Heytings <gregory@heytings.org>
Tue, 2 Nov 2021 14:50:31 +0000 (15:50 +0100)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 2 Nov 2021 14:50:31 +0000 (15:50 +0100)
* doc/lispref/files.texi: Update the documentation.

* lisp/net/mailcap.el: Add a second argument to the call to
file-has-changed-p (bug#51523).

doc/lispref/files.texi
lisp/files.el
lisp/net/mailcap.el

index b7420fc678f60deb63f376d771074f905d91061f..84da6eba2fce52ff429db4b582f8a6a2109f1ab3 100644 (file)
@@ -1314,15 +1314,17 @@ on the 19th, @file{aug-20} was written on the 20th, and the file
 @end example
 @end defun
 
-@defun file-has-changed-p filename
+@defun file-has-changed-p filename tag
 This function returns non-@code{nil} if the time stamp of
 @var{filename} has changed since the last call.  When called for the
 first time for some @var{filename}, it records the last modification
-time of the file and returns non-@code{nil}.  Thereafter, when called
-for the same @var{filename}, it compares the current time stamp with
-the recorded one and returns non-@code{nil} only if they are
-different.  This is useful when a Lisp program wants to re-read a file
-whenever it changes.
+time ans size of the file and returns non-@code{nil}.  Thereafter,
+when called for the same @var{filename}, it compares the current time
+stamp and size with the recorded one and returns non-@code{nil} only
+if they are different.  This is useful when a Lisp program wants to
+re-read a file whenever it changes.  With an optional argument
+@var{tag}, the size and modification time comparisons are limited to
+calls with the same tag.
 @end defun
 
 @defun file-attributes filename &optional id-format
index 5e7be3844ebcf800eb7ca2163731affde6a4ace4..d7dfa9399e20ae271386baa7071896cfe0a46cb1 100644 (file)
@@ -6181,21 +6181,25 @@ Return nil if DIR is not an existing directory."
          (unless mismatch
            (file-equal-p root dir)))))))
 
-(defvar file-has-changed-p--hash-table (make-hash-table)
+(defvar file-has-changed-p--hash-table (make-hash-table :test #'equal)
   "Internal variable used by `file-has-changed-p'.")
 
-(defun file-has-changed-p (file)
+(defun file-has-changed-p (file &optional tag)
   "Return non-nil if FILE has changed.
-The modification time of FILE is compared to the modification
-time of FILE during a previous invocation of `file-has-changed-p'.
-Therefore the first invocation of `file-has-changed-p' always
-returns non-nil."
-  (let* ((attr (file-attributes file 'integer))
-         (mtime (file-attribute-modification-time attr))
-         (saved-mtime (gethash (intern file)
-                               file-has-changed-p--hash-table)))
-     (when (not (equal mtime saved-mtime))
-       (puthash (intern file) mtime file-has-changed-p--hash-table))))
+The size and modification time of FILE is compared to the size
+and modification time of FILE during a previous invocation of
+`file-has-changed-p'.  Therefore the first invocation of
+`file-has-changed-p' always returns non-nil.
+The optional argument TAG can be used to limit the comparison to
+invocations with identical tags; it can for example be the symbol
+of the calling function."
+  (let* ((fileattr (file-attributes file 'integer))
+        (attr (cons (file-attribute-size fileattr)
+                    (file-attribute-modification-time fileattr)))
+        (sym (concat (symbol-name tag) "@" file))
+        (cachedattr (gethash sym file-has-changed-p--hash-table)))
+     (when (not (equal attr cachedattr))
+       (puthash sym attr file-has-changed-p--hash-table))))
 
 (defun copy-directory (directory newname &optional keep-time parents copy-contents)
   "Copy DIRECTORY to NEWNAME.  Both args must be strings.
index 4dedd38c22c02818d2c51fc5b137403442d11ea0..e40cf2a336dca4afb868cd0382812f6889765e2e 100644 (file)
@@ -447,7 +447,9 @@ MAILCAPS if set; otherwise (on Unix) use the path from RFC 1524, plus
               ("/etc/mailcap" system)
               ("/usr/etc/mailcap" system)
              ("/usr/local/etc/mailcap" system)))))
-    (when (seq-some (lambda (f) (file-has-changed-p (car f))) path)
+    (when (seq-some (lambda (f)
+                      (file-has-changed-p (car f) 'mail-parse-mailcaps))
+                    path)
       ;; The ~/.mailcap entries will end up first in the resulting data.
       (dolist (spec (reverse
                     (if (stringp path)