From a743c2beb30905ac49b4a6af10777c662a9d67a0 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sat, 23 Nov 2024 22:05:33 -0500 Subject: [PATCH] (dir-locals-collect-variables): Don't autoload if not needed (bug#74349) While dir-local settings for `c-mode` may require (auto)loading `cc-mode.el` to get all the `safe-local-variable` properties, they may not. So before (auto)loading that file, make sure we don't already have all the `safe-local-variable` properties we need. * lisp/files.el (dir-locals--load-mode-if-needed): New function. (hack-one-local-variable): Don't inf-loop if `eval` calls a major mode. (dir-locals-collect-variables): Use `dir-locals--load-mode-if-needed`. (cherry picked from commit f713258416f224b93e4f25b2db24d5e8797bcbff) --- lisp/files.el | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index 2274ff54287..bdcf0f4c00d 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4486,7 +4486,8 @@ already the major mode." ('eval (pcase val (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook))) - (save-excursion (eval val t))) + (let ((enable-local-variables nil)) ;FIXME: Should be buffer-local! + (save-excursion (eval val t)))) (_ (hack-one-local-variable--obsolete var) ;; Make sure the string has no text properties. @@ -4532,6 +4533,21 @@ Returns the new list." ;; Need a new cons in case we setcdr later. (push (cons variable value) variables))))) +(defun dir-locals--load-mode-if-needed (key alist) + ;; If KEY is an extra parent it may remain not loaded + ;; (hence with some of its mode-specific vars missing their + ;; `safe-local-variable' property), leading to spurious + ;; prompts about unsafe vars (bug#68246). + (when (and (symbolp key) (autoloadp (indirect-function key))) + (let ((unsafe nil)) + (pcase-dolist (`(,var . ,_val) alist) + (unless (or (memq var '(mode eval)) + (get var 'safe-local-variable)) + (setq unsafe t))) + (when unsafe + (ignore-errors + (autoload-do-load (indirect-function key))))))) + (defun dir-locals-collect-variables (class-variables root variables &optional predicate) "Collect entries from CLASS-VARIABLES into VARIABLES. @@ -4562,15 +4578,9 @@ to see whether it should be considered." (funcall predicate key) (or (not key) (derived-mode-p key))) - ;; If KEY is an extra parent it may remain not loaded - ;; (hence with some of its mode-specific vars missing their - ;; `safe-local-variable' property), leading to spurious - ;; prompts about unsafe vars (bug#68246). - (if (and (symbolp key) (autoloadp (indirect-function key))) - (ignore-errors (autoload-do-load (indirect-function key)))) (let* ((alist (cdr entry)) (subdirs (assq 'subdirs alist))) - (if (or (not subdirs) + (when (or (not subdirs) (progn (setq alist (remq subdirs alist)) (cdr-safe subdirs)) @@ -4579,6 +4589,7 @@ to see whether it should be considered." ;; variables apply to this directory and N levels ;; below it (0 == nil). (equal root (expand-file-name default-directory))) + (dir-locals--load-mode-if-needed key alist) (setq variables (dir-locals-collect-mode-variables alist variables)))))))) (error -- 2.39.5