From: Michael Albinus Date: Thu, 13 May 2021 11:57:46 +0000 (+0200) Subject: Fix bug#48349 in file-name-non-special X-Git-Tag: emacs-28.0.90~2484 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=1b919004f65f6987c5815e7d65a00b78e19fc7ac;p=emacs.git Fix bug#48349 in file-name-non-special * lisp/files.el (file-name-non-special): Use Tramp file name handler only in case of `copy-file', 'rename-file' and `copy-directory'. (Bug#48349) --- diff --git a/lisp/files.el b/lisp/files.el index 60f72660f36..4fdafe19db9 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -7492,12 +7492,7 @@ only these files will be asked to be saved." ;; operations, which return a file name. See Bug#29579. (defun file-name-non-special (operation &rest arguments) - (let (;; In general, we don't want any file name handler. For some - ;; few cases, operations with two file name arguments which - ;; might be bound to different file name handlers, we still - ;; need this. - (saved-file-name-handler-alist file-name-handler-alist) - (inhibit-file-name-handlers + (let ((inhibit-file-name-handlers (cons 'file-name-non-special (and (eq inhibit-file-name-operation operation) inhibit-file-name-handlers))) @@ -7583,72 +7578,73 @@ only these files will be asked to be saved." (when (car pair) (setcar pair (file-name-unquote (car pair) t)))) (setq file-arg-indices (cdr file-arg-indices)))) - (pcase method - ('identity (car arguments)) - ('add - ;; This is `file-truename'. We don't want file name handlers - ;; to expand this. - (file-name-quote (let (tramp-mode) (apply operation arguments)) t)) - ('buffer-file-name - (let ((buffer-file-name (file-name-unquote buffer-file-name t))) - (apply operation arguments))) - ('insert-file-contents - (let ((visit (nth 1 arguments))) - (unwind-protect - (apply operation arguments) - (when (and visit buffer-file-name) - (setq buffer-file-name (file-name-quote buffer-file-name t)))))) - ('unquote-then-quote - ;; We can't use `cl-letf' with `(buffer-local-value)' here - ;; because it wouldn't work during bootstrapping. - (let ((buffer (current-buffer))) - ;; `unquote-then-quote' is used only for the - ;; `verify-visited-file-modtime' action, which takes a buffer - ;; as only optional argument. - (with-current-buffer (or (car arguments) buffer) - (let ((buffer-file-name (file-name-unquote buffer-file-name t))) - ;; Make sure to hide the temporary buffer change from the - ;; underlying operation. - (with-current-buffer buffer - (apply operation arguments)))))) - ('local-copy - (let* ((file-name-handler-alist saved-file-name-handler-alist) - (source (car arguments)) - (target (car (cdr arguments))) - (prefix (expand-file-name - "file-name-non-special" temporary-file-directory)) - tmpfile) - (cond - ;; If source is remote, we must create a local copy. - ((file-remote-p source) - (setq tmpfile (make-temp-name prefix)) - (apply operation source tmpfile (cddr arguments)) - (setq source tmpfile)) - ;; If source is quoted, and the unquoted source looks - ;; remote, we must create a local copy. - ((file-name-quoted-p source t) - (setq source (file-name-unquote source t)) - (when (file-remote-p source) + ;; In general, we don't want any file name handler, see Bug#47625, + ;; Bug#48349. For some few cases, operations with two file name + ;; arguments which might be bound to different file name handlers, + ;; we still need this. + (let ((tramp-mode (and tramp-mode (eq method 'local-copy)))) + (pcase method + ('identity (car arguments)) + ('add (file-name-quote (apply operation arguments) t)) + ('buffer-file-name + (let ((buffer-file-name (file-name-unquote buffer-file-name t))) + (apply operation arguments))) + ('insert-file-contents + (let ((visit (nth 1 arguments))) + (unwind-protect + (apply operation arguments) + (when (and visit buffer-file-name) + (setq buffer-file-name (file-name-quote buffer-file-name t)))))) + ('unquote-then-quote + ;; We can't use `cl-letf' with `(buffer-local-value)' here + ;; because it wouldn't work during bootstrapping. + (let ((buffer (current-buffer))) + ;; `unquote-then-quote' is used only for the + ;; `verify-visited-file-modtime' action, which takes a + ;; buffer as only optional argument. + (with-current-buffer (or (car arguments) buffer) + (let ((buffer-file-name (file-name-unquote buffer-file-name t))) + ;; Make sure to hide the temporary buffer change from + ;; the underlying operation. + (with-current-buffer buffer + (apply operation arguments)))))) + ('local-copy + (let ((source (car arguments)) + (target (car (cdr arguments))) + (prefix (expand-file-name + "file-name-non-special" temporary-file-directory)) + tmpfile) + (cond + ;; If source is remote, we must create a local copy. + ((file-remote-p source) (setq tmpfile (make-temp-name prefix)) - (let (file-name-handler-alist) - (apply operation source tmpfile (cddr arguments))) - (setq source tmpfile)))) - ;; If target is quoted, and the unquoted target looks remote, - ;; we must disable the file name handler. - (when (file-name-quoted-p target t) - (setq target (file-name-unquote target t)) - (when (file-remote-p target) - (setq file-name-handler-alist nil))) - ;; Do it. - (setcar arguments source) - (setcar (cdr arguments) target) - (apply operation arguments) - ;; Cleanup. - (when (and tmpfile (file-exists-p tmpfile)) - (if (file-directory-p tmpfile) - (delete-directory tmpfile 'recursive) (delete-file tmpfile))))) - (_ - (apply operation arguments))))) + (apply operation source tmpfile (cddr arguments)) + (setq source tmpfile)) + ;; If source is quoted, and the unquoted source looks + ;; remote, we must create a local copy. + ((file-name-quoted-p source t) + (setq source (file-name-unquote source t)) + (when (file-remote-p source) + (setq tmpfile (make-temp-name prefix)) + (let (file-name-handler-alist) + (apply operation source tmpfile (cddr arguments))) + (setq source tmpfile)))) + ;; If target is quoted, and the unquoted target looks + ;; remote, we must disable the file name handler. + (when (file-name-quoted-p target t) + (setq target (file-name-unquote target t)) + (when (file-remote-p target) + (setq file-name-handler-alist nil))) + ;; Do it. + (setcar arguments source) + (setcar (cdr arguments) target) + (apply operation arguments) + ;; Cleanup. + (when (and tmpfile (file-exists-p tmpfile)) + (if (file-directory-p tmpfile) + (delete-directory tmpfile 'recursive) (delete-file tmpfile))))) + (_ + (apply operation arguments)))))) (defsubst file-name-quoted-p (name &optional top) "Whether NAME is quoted with prefix \"/:\".