emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 53a9a2d: Improve file-has-changed-p


From: Lars Ingebrigtsen
Subject: master 53a9a2d: Improve file-has-changed-p
Date: Tue, 2 Nov 2021 10:50:58 -0400 (EDT)

branch: master
commit 53a9a2de456b2db8d126bbc71becd5ae86a1f172
Author: Gregory Heytings <gregory@heytings.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Improve file-has-changed-p
    
    * 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 | 14 ++++++++------
 lisp/files.el          | 28 ++++++++++++++++------------
 lisp/net/mailcap.el    |  4 +++-
 3 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index b7420fc..84da6eb 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -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
diff --git a/lisp/files.el b/lisp/files.el
index 5e7be38..d7dfa93 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -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.
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index 4dedd38..e40cf2a 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]