master bfc1998fb94: New macro without-local-variable-queries (bug#81233)
Sean Whitton <[email protected]> Tue, 7 Jul 2026 09:30:38 -0400 (EDT)
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: master commit bfc1998fb9401f85b97f2f67149c912d89606188 Author: Sean Whitton <[email protected]> Commit: Sean Whitton <[email protected]> New macro without-local-variable-queries (bug#81233) * lisp/files.el (without-local-variable-queries): New macro. * lisp/vc/diff-mode.el (diff-syntax-fontify-props): * lisp/vc/vc-dir.el (vc-dir--count-outgoing): * lisp/vc/vc.el (vc-find-revision-no-save): Use it. * lisp/files.el (hack-local-variables-confirm): Warn when it looks like the caller should have used it. --- lisp/files.el | 15 ++++++++++++ lisp/vc/diff-mode.el | 38 +++++++++++++++--------------- lisp/vc/vc-dir.el | 65 ++++++++++++++++++++++++++-------------------------- lisp/vc/vc.el | 20 ++++++++-------- 4 files changed, 76 insertions(+), 62 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index fa120f5c8ae..27a69b3fc81 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -3991,6 +3991,18 @@ variable `enable-remote-dir-locals' is non-nil." :risky t :group 'find-file) +(defmacro without-local-variable-queries (&rest body) + "Execute BODY without querying user about local variable values. +In some uses, this is a workaround for the problem that a command +disables displaying new windows for its own reasons but this also breaks +`hack-local-variables-confirm'. See Emacs bug#80528 and bug#81233." + (declare (indent 0) (debug t)) + `(let ((enable-local-variables + (if (memq enable-local-variables '(:safe :all nil)) + enable-local-variables + :safe))) + ,@body)) + (defun hack-local-variables-confirm (all-vars unsafe-vars risky-vars dir-name) "Get confirmation before setting up local variable values. ALL-VARS is the list of all variables to be set up. @@ -4055,6 +4067,9 @@ i -- to ignore the local variables list, and permanently mark these ;; Display the buffer and read a choice. (save-window-excursion (pop-to-buffer buf '(display-buffer--maybe-at-bottom)) + (unless (get-buffer-window buf) + (error "Failed to display local variables buffer; this is a bug +Possibly caller should use `without-local-variable-queries', which see.")) (let* ((exit-chars '(?y ?n ?\s)) (prompt (format "Please type %s%s: " (if offer-save diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index c1227573351..0ee055424c8 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -3504,25 +3504,25 @@ hunk text is not found in the source file." ;; When initialization is requested, we should be in a brand new ;; temp buffer. (cl-assert (null buffer-file-name)) - ;; Use `:safe' to find `mode:'. In case of hunk-only, use nil because - ;; Local Variables list might be incomplete when context is truncated. - (let ((enable-local-variables - (unless hunk-only - (if (memq enable-local-variables '(:safe :all nil)) - enable-local-variables - ;; Ignore other values that query. - :safe))) - (buffer-file-name file)) - ;; Don't run hooks that might assume buffer-file-name - ;; really associates buffer with a file (bug#39190). - (delay-mode-hooks (set-auto-mode)) - ;; FIXME: Is this really worth the trouble? - (when (and (fboundp 'generic-mode-find-file-hook) - (memq #'generic-mode-find-file-hook - ;; There's no point checking the buffer-local value, - ;; we're in a fresh new buffer. - (default-value 'find-file-hook))) - (generic-mode-find-file-hook)))) + (cl-flet + ((set-mode () + ;; Don't run hooks that might assume buffer-file-name + ;; really associates buffer with a file (bug#39190). + (delay-mode-hooks (set-auto-mode)) + ;; FIXME: Is this really worth the trouble? + (when (and (fboundp 'generic-mode-find-file-hook) + (memq #'generic-mode-find-file-hook + ;; There's no point checking the + ;; buffer-local value because we're in a + ;; fresh new buffer. + (default-value 'find-file-hook))) + (generic-mode-find-file-hook)))) + ;; Use `:safe' to find `mode:'. In case of hunk-only, use nil because + ;; Local Variables list might be incomplete when context is truncated. + (let ((buffer-file-name file)) + (if hunk-only + (let (enable-local-variables) (set-mode)) + (without-local-variable-queries (set-mode)))))) (let ((font-lock-defaults (or font-lock-defaults '(nil t))) props beg end) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index ff019bbbb8d..383e55e8444 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -1534,39 +1534,40 @@ uses OVERLAY." (unknown (propertize "<<unknown>>" 'face 'vc-dir-header-value)) (buf (generate-new-buffer " *temp*" t)) proc) - (with-current-buffer buf - (condition-case _ - (progn - (vc-incoming-outgoing-internal backend nil - (current-buffer) - '(log-outgoing short)) - (setq proc (get-buffer-process (current-buffer))) - (overlay-put overlay 'proc proc) - (vc-run-delayed - (unwind-protect - (overlay-put - overlay 'after-string - (if (or (not (eq (process-status proc) 'exit)) - (plusp (process-exit-status proc))) - unknown - (goto-char (point-min)) - (let ((count (how-many log-view-message-re))) - (if (zerop count) - (propertize "No unpushed revisions" - 'face 'vc-dir-header-value) - (propertize - (format (ngettext "%d unpushed revision" - "%d unpushed revisions" - count) - count) - 'face 'vc-dir-header-urgent-value - 'mouse-face 'highlight - 'keymap vc-dir-outgoing-revisions-map - 'help-echo "\\<vc-dir-outgoing-revisions-map>\ + (without-local-variable-queries + (with-current-buffer buf + (condition-case _ + (progn + (vc-incoming-outgoing-internal backend nil + (current-buffer) + '(log-outgoing short)) + (setq proc (get-buffer-process (current-buffer))) + (overlay-put overlay 'proc proc) + (vc-run-delayed + (unwind-protect + (overlay-put + overlay 'after-string + (if (or (not (eq (process-status proc) 'exit)) + (plusp (process-exit-status proc))) + unknown + (goto-char (point-min)) + (let ((count (how-many log-view-message-re))) + (if (zerop count) + (propertize "No unpushed revisions" + 'face 'vc-dir-header-value) + (propertize + (format (ngettext "%d unpushed revision" + "%d unpushed revisions" + count) + count) + 'face 'vc-dir-header-urgent-value + 'mouse-face 'highlight + 'keymap vc-dir-outgoing-revisions-map + 'help-echo "\\<vc-dir-outgoing-revisions-map>\ \\[vc-root-log-outgoing]: List outgoing revisions"))))) - (kill-buffer)))) - (error (overlay-put overlay 'after-string unknown) - (kill-buffer buf))))))))) + (kill-buffer)))) + (error (overlay-put overlay 'after-string unknown) + (kill-buffer buf)))))))))) (defvar-local vc-dir-async-header-values '(("Outgoing" . vc-dir--count-outgoing)) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 33e3e5dced2..766551ca1ef 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -3871,17 +3871,15 @@ Unlike `vc-find-revision-save', doesn't save the buffer to the file." (after-insert-file-set-coding (- (point-max) (point-min))) (goto-char (point-min)) (if buffer - ;; For non-interactive, skip any questions - (let ((enable-local-variables - (if (memq enable-local-variables '(:safe :all nil)) - enable-local-variables - ;; Ignore other values that query, - ;; use `:safe' to find `mode:'. - :safe)) - (buffer-file-name file)) - ;; Don't run hooks that might assume buffer-file-name - ;; really associates buffer with a file (bug#39190). - (ignore-errors (delay-mode-hooks (set-auto-mode)))) + ;; For non-interactive, skip any questions. + ;; Use `:safe' to find `mode:'. + (without-local-variable-queries + (let ((buffer-file-name file)) + ;; Don't run hooks that might assume + ;; buffer-file-name really associates buffer + ;; with a file (bug#39190). + (ignore-errors + (delay-mode-hooks (set-auto-mode))))) ;; Use non-nil 'find-file' arg of 'normal-mode' ;; to not ignore 'enable-local-variables' when nil. (normal-mode (not enable-local-variables)))