From 4106b342fe40d4b585f43c19ba45ccc6f3f6c1e1 Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Mon, 1 Nov 2021 09:25:23 +0000 Subject: [PATCH] Read mailcaps again only when necessary. * lisp/net/mailcap.el (mailcap-parse-mailcaps): Read mailcaps again only when at least one of the mailcap files has changed. Fixes bug#51523. * lisp/files.el (file-has-changed-p): New function. (file-has-changed-p--hash-table): Internal variable used by the new function. --- lisp/files.el | 16 ++++++++++++++++ lisp/net/mailcap.el | 25 +++++++++++++------------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index 1e65d0ce83..5e7be3844e 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6181,6 +6181,22 @@ file-in-directory-p (unless mismatch (file-equal-p root dir))))))) +(defvar file-has-changed-p--hash-table (make-hash-table) + "Internal variable used by `file-has-changed-p'.") + +(defun file-has-changed-p (file) + "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)))) + (defun copy-directory (directory newname &optional keep-time parents copy-contents) "Copy DIRECTORY to NEWNAME. Both args must be strings. This function always sets the file modes of the output files to match diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el index 83d0eeef9f..4dedd38c22 100644 --- a/lisp/net/mailcap.el +++ b/lisp/net/mailcap.el @@ -447,18 +447,19 @@ mailcap-parse-mailcaps ("/etc/mailcap" system) ("/usr/etc/mailcap" system) ("/usr/local/etc/mailcap" system))))) - ;; The ~/.mailcap entries will end up first in the resulting data. - (dolist (spec (reverse - (if (stringp path) - (split-string path path-separator t) - path))) - (let ((source (and (consp spec) (cadr spec))) - (file-name (if (stringp spec) - spec - (car spec)))) - (when (and (file-readable-p file-name) - (file-regular-p file-name)) - (mailcap-parse-mailcap file-name source)))) + (when (seq-some (lambda (f) (file-has-changed-p (car f))) path) + ;; The ~/.mailcap entries will end up first in the resulting data. + (dolist (spec (reverse + (if (stringp path) + (split-string path path-separator t) + path))) + (let ((source (and (consp spec) (cadr spec))) + (file-name (if (stringp spec) + spec + (car spec)))) + (when (and (file-readable-p file-name) + (file-regular-p file-name)) + (mailcap-parse-mailcap file-name source))))) (setq mailcap-parsed-p t))) (defun mailcap-parse-mailcap (fname &optional source) -- 2.33.0