From bb1f70c90180589564e1f831725c59e34013b02a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 23 Nov 2025 10:32:18 +0200 Subject: [PATCH] Fix 'd' command in 'query-replace' in buffers not visiting files * lisp/vc/diff.el (diff-file-local-copy): Use proper coding-system when writing a local copy of a non-file visiting buffer. * lisp/misearch.el (coding-system--for-buffer-diff): New variable. (multi-file-replace-as-diff): Bind it to 'utf-8-emacs'. (multi-file-diff-no-select): Use proper coding-system when reading output of Diff. (Bug#79761) --- lisp/misearch.el | 13 +++++++++++-- lisp/vc/diff.el | 6 +++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lisp/misearch.el b/lisp/misearch.el index c20b75bf6f0..28cda1fcbf0 100644 --- a/lisp/misearch.el +++ b/lisp/misearch.el @@ -406,6 +406,9 @@ modified buffer to be able to use unsaved changes." (declare-function diff-setup-whitespace "diff-mode" ()) (declare-function diff-setup-buffer-type "diff-mode" ()) +(defvar coding-system--for-buffer-diff nil + "Used to pass encoding down to callees of `multi-file-diff-no-select'.") + ;;;###autoload (defun multi-file-replace-as-diff (files from-string replacements regexp-flag delimited-flag) "Show as diffs replacements of FROM-STRING with REPLACEMENTS. @@ -439,7 +442,11 @@ as in `perform-replace'." file-name (when (or (not file-exists) (eq multi-file-diff-unsaved 'use-modified-buffer)) - (find-buffer-visiting file-name))))) + (find-buffer-visiting file-name)))) + ;; Make sure any supported characters can be written to a + ;; file without asking the user to select a safe + ;; coding-system. + (coding-system--for-buffer-diff 'utf-8-emacs)) (when non-file-buffer (setq file-name (buffer-name file-name))) (when (or file-exists file-buffer) (with-temp-buffer @@ -540,7 +547,9 @@ specify labels to use for file names." (or new-alt new))))) " "))) (with-current-buffer buf - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) + (coding-system-for-read (or coding-system--for-buffer-diff + coding-system-for-read))) (insert command "\n") (call-process shell-file-name nil buf nil shell-command-switch command)) diff --git a/lisp/vc/diff.el b/lisp/vc/diff.el index c8a1b7c0efa..9e4a5349fef 100644 --- a/lisp/vc/diff.el +++ b/lisp/vc/diff.el @@ -118,13 +118,17 @@ Non-interactively, OLD and NEW may each be a file or a buffer." (display-buffer (diff-no-select old new switches no-async))) +(defvar coding-system--for-buffer-diff) ; from misearch.el + (defun diff-file-local-copy (file-or-buf) "Like `file-local-copy' but also supports a buffer as the argument. When FILE-OR-BUF is a buffer, return the filename of a local temporary file with the buffer's contents." (if (bufferp file-or-buf) (with-current-buffer file-or-buf - (let ((tempfile (make-temp-file "buffer-content-"))) + (let ((tempfile (make-temp-file "buffer-content-")) + (coding-system-for-write (or coding-system--for-buffer-diff + coding-system-for-write))) (if diff-entire-buffers (write-region nil nil tempfile nil 'nomessage) (write-region (point-min) (point-max) tempfile nil 'nomessage))