diff options
| author | Michael Albinus | 2018-06-04 18:15:54 +0200 |
|---|---|---|
| committer | Michael Albinus | 2018-06-04 18:15:54 +0200 |
| commit | 5e307525b907601ccda2a7914fea898366b25b91 (patch) | |
| tree | a3c0c387b06b430954a34fd4fd19191866d6e1f7 | |
| parent | 9a0b20d5b33e3e3282b597c3d0c836396071a547 (diff) | |
| download | emacs-5e307525b907601ccda2a7914fea898366b25b91.tar.gz emacs-5e307525b907601ccda2a7914fea898366b25b91.zip | |
Fix Bug#31489
* lisp/files.el (file-name-unquote-non-special): Remove.
(file-name-quoted-p, file-name-quote, file-name-unquote):
Add optional argument TOP.
(file-name-non-special): Adapt callees. Finish implementation of
functions which need a local copy. (Bug#31489)
| -rw-r--r-- | lisp/files.el | 112 |
1 files changed, 57 insertions, 55 deletions
diff --git a/lisp/files.el b/lisp/files.el index 68423f87bbf..dbe95bb6659 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -7044,8 +7044,7 @@ only these files will be asked to be saved." | |||
| 7044 | ;; Use a temporary local copy. | 7044 | ;; Use a temporary local copy. |
| 7045 | (copy-file local-copy) | 7045 | (copy-file local-copy) |
| 7046 | (rename-file local-copy) | 7046 | (rename-file local-copy) |
| 7047 | ;;`copy-directory' needs special handling. | 7047 | (copy-directory local-copy) |
| 7048 | (copy-directory copy-directory) | ||
| 7049 | ;; List the arguments which are filenames. | 7048 | ;; List the arguments which are filenames. |
| 7050 | (file-name-completion 0 1) | 7049 | (file-name-completion 0 1) |
| 7051 | (file-name-all-completions 0 1) | 7050 | (file-name-all-completions 0 1) |
| @@ -7072,21 +7071,20 @@ only these files will be asked to be saved." | |||
| 7072 | (while (consp file-arg-indices) | 7071 | (while (consp file-arg-indices) |
| 7073 | (let ((pair (nthcdr (car file-arg-indices) arguments))) | 7072 | (let ((pair (nthcdr (car file-arg-indices) arguments))) |
| 7074 | (when (car pair) | 7073 | (when (car pair) |
| 7075 | (setcar pair (file-name-unquote-non-special (car pair))))) | 7074 | (setcar pair (file-name-unquote (car pair) t)))) |
| 7076 | (setq file-arg-indices (cdr file-arg-indices)))) | 7075 | (setq file-arg-indices (cdr file-arg-indices)))) |
| 7077 | (pcase method | 7076 | (pcase method |
| 7078 | (`identity (car arguments)) | 7077 | (`identity (car arguments)) |
| 7079 | (`add (file-name-quote (apply operation arguments))) | 7078 | (`add (file-name-quote (apply operation arguments) t)) |
| 7080 | (`buffer-file-name | 7079 | (`buffer-file-name |
| 7081 | (let ((buffer-file-name | 7080 | (let ((buffer-file-name (file-name-unquote buffer-file-name t))) |
| 7082 | (file-name-unquote-non-special buffer-file-name))) | ||
| 7083 | (apply operation arguments))) | 7081 | (apply operation arguments))) |
| 7084 | (`insert-file-contents | 7082 | (`insert-file-contents |
| 7085 | (let ((visit (nth 1 arguments))) | 7083 | (let ((visit (nth 1 arguments))) |
| 7086 | (unwind-protect | 7084 | (unwind-protect |
| 7087 | (apply operation arguments) | 7085 | (apply operation arguments) |
| 7088 | (when (and visit buffer-file-name) | 7086 | (when (and visit buffer-file-name) |
| 7089 | (setq buffer-file-name (file-name-quote buffer-file-name)))))) | 7087 | (setq buffer-file-name (file-name-quote buffer-file-name t)))))) |
| 7090 | (`unquote-then-quote | 7088 | (`unquote-then-quote |
| 7091 | ;; We can't use `cl-letf' with `(buffer-local-value)' here | 7089 | ;; We can't use `cl-letf' with `(buffer-local-value)' here |
| 7092 | ;; because it wouldn't work during bootstrapping. | 7090 | ;; because it wouldn't work during bootstrapping. |
| @@ -7095,8 +7093,7 @@ only these files will be asked to be saved." | |||
| 7095 | ;; `verify-visited-file-modtime' action, which takes a buffer | 7093 | ;; `verify-visited-file-modtime' action, which takes a buffer |
| 7096 | ;; as only optional argument. | 7094 | ;; as only optional argument. |
| 7097 | (with-current-buffer (or (car arguments) buffer) | 7095 | (with-current-buffer (or (car arguments) buffer) |
| 7098 | (let ((buffer-file-name | 7096 | (let ((buffer-file-name (file-name-unquote buffer-file-name t))) |
| 7099 | (file-name-unquote-non-special buffer-file-name))) | ||
| 7100 | ;; Make sure to hide the temporary buffer change from the | 7097 | ;; Make sure to hide the temporary buffer change from the |
| 7101 | ;; underlying operation. | 7098 | ;; underlying operation. |
| 7102 | (with-current-buffer buffer | 7099 | (with-current-buffer buffer |
| @@ -7105,62 +7102,67 @@ only these files will be asked to be saved." | |||
| 7105 | (let* ((file-name-handler-alist saved-file-name-handler-alist) | 7102 | (let* ((file-name-handler-alist saved-file-name-handler-alist) |
| 7106 | (source (car arguments)) | 7103 | (source (car arguments)) |
| 7107 | (target (car (cdr arguments))) | 7104 | (target (car (cdr arguments))) |
| 7108 | (tmpfile (file-local-copy source))) | 7105 | (prefix (expand-file-name |
| 7109 | (let ((handler (find-file-name-handler target 'copy-file))) | 7106 | "file-name-non-special" temporary-file-directory)) |
| 7110 | (unless (and handler (not (eq handler 'file-name-non-special))) | 7107 | tmpfile) |
| 7111 | (setq target (file-name-unquote-non-special target)))) | 7108 | (cond |
| 7112 | (setcar arguments (or tmpfile (file-name-unquote-non-special source))) | 7109 | ;; If source is remote, we must create a local copy. |
| 7113 | (setcar (cdr arguments) target) | 7110 | ((file-remote-p source) |
| 7114 | (apply operation arguments) | 7111 | (setq tmpfile (make-temp-name prefix)) |
| 7115 | (when (and tmpfile (file-exists-p tmpfile)) (delete-file tmpfile)))) | 7112 | (apply operation source tmpfile (cddr arguments)) |
| 7116 | (`copy-directory | 7113 | (setq source tmpfile)) |
| 7117 | (let* ((file-name-handler-alist saved-file-name-handler-alist) | 7114 | ;; If source is quoted, and the unquoted source looks |
| 7118 | (source (car arguments)) | 7115 | ;; remote, we must create a local copy. |
| 7119 | (target (car (cdr arguments))) | 7116 | ((file-name-quoted-p source t) |
| 7120 | tmpdir) | 7117 | (setq source (file-name-unquote source t)) |
| 7121 | (let ((handler (find-file-name-handler source 'copy-directory))) | 7118 | (when (file-remote-p source) |
| 7122 | (if (and handler (not (eq handler 'file-name-non-special))) | 7119 | (setq tmpfile (make-temp-name prefix)) |
| 7123 | (progn | 7120 | (let (file-name-handler-alist) |
| 7124 | (setq tmpdir (make-temp-name temporary-file-directory)) | 7121 | (apply operation source tmpfile (cddr arguments))) |
| 7125 | (setcar (cdr arguments) tmpdir) | 7122 | (setq source tmpfile)))) |
| 7126 | (apply operation arguments) | 7123 | ;; If target is quoted, and the unquoted target looks remote, |
| 7127 | (setq source tmpdir)) | 7124 | ;; we must disable the file name handler. |
| 7128 | (setq source (file-name-unquote-non-special source)))) | 7125 | (when (file-name-quoted-p target t) |
| 7129 | (let ((handler (find-file-name-handler target 'copy-directory))) | 7126 | (setq target (file-name-unquote target t)) |
| 7130 | (unless (and handler (not (eq handler 'file-name-non-special))) | 7127 | (when (file-remote-p target) |
| 7131 | (setq target (file-name-unquote-non-special target)))) | 7128 | (setq file-name-handler-alist nil))) |
| 7129 | ;; Do it. | ||
| 7132 | (setcar arguments source) | 7130 | (setcar arguments source) |
| 7133 | (setcar (cdr arguments) target) | 7131 | (setcar (cdr arguments) target) |
| 7134 | (apply operation arguments) | 7132 | (apply operation arguments) |
| 7135 | (when tmpdir (delete-directory tmpdir 'recursive)))) | 7133 | ;; Cleanup. |
| 7134 | (when (and tmpfile (file-exists-p tmpfile)) | ||
| 7135 | (if (file-directory-p tmpfile) | ||
| 7136 | (delete-directory tmpfile 'recursive) (delete-file tmpfile))))) | ||
| 7136 | (_ | 7137 | (_ |
| 7137 | (apply operation arguments))))) | 7138 | (apply operation arguments))))) |
| 7138 | 7139 | ||
| 7139 | (defsubst file-name-quoted-p (name) | 7140 | (defsubst file-name-quoted-p (name &optional top) |
| 7140 | "Whether NAME is quoted with prefix \"/:\". | 7141 | "Whether NAME is quoted with prefix \"/:\". |
| 7141 | If NAME is a remote file name, check the local part of NAME." | 7142 | If NAME is a remote file name and TOP is nil, check the local part of NAME." |
| 7142 | (string-prefix-p "/:" (file-local-name name))) | 7143 | (let ((file-name-handler-alist (unless top file-name-handler-alist))) |
| 7144 | (string-prefix-p "/:" (file-local-name name)))) | ||
| 7143 | 7145 | ||
| 7144 | (defsubst file-name-quote (name) | 7146 | (defsubst file-name-quote (name &optional top) |
| 7145 | "Add the quotation prefix \"/:\" to file NAME. | 7147 | "Add the quotation prefix \"/:\" to file NAME. |
| 7146 | If NAME is a remote file name, the local part of NAME is quoted. | 7148 | If NAME is a remote file name and TOP is nil, the local part of |
| 7147 | If NAME is already a quoted file name, NAME is returned unchanged." | 7149 | NAME is quoted. If NAME is already a quoted file name, NAME is |
| 7148 | (if (file-name-quoted-p name) | 7150 | returned unchanged." |
| 7149 | name | 7151 | (let ((file-name-handler-alist (unless top file-name-handler-alist))) |
| 7150 | (concat (file-remote-p name) "/:" (file-local-name name)))) | 7152 | (if (file-name-quoted-p name top) |
| 7151 | 7153 | name | |
| 7152 | (defsubst file-name-unquote-non-special (name) | 7154 | (concat (file-remote-p name) "/:" (file-local-name name))))) |
| 7153 | "Remove quotation prefix \"/:\" from file NAME, if any." | 7155 | |
| 7154 | (let (file-name-handler-alist) | 7156 | (defsubst file-name-unquote (name &optional top) |
| 7155 | (if (file-name-quoted-p name) | ||
| 7156 | (if (= (length name) 2) "/" (substring name 2)) | ||
| 7157 | name))) | ||
| 7158 | |||
| 7159 | (defsubst file-name-unquote (name) | ||
| 7160 | "Remove quotation prefix \"/:\" from file NAME, if any. | 7157 | "Remove quotation prefix \"/:\" from file NAME, if any. |
| 7161 | If NAME is a remote file name, the local part of NAME is unquoted." | 7158 | If NAME is a remote file name and TOP is nil, the local part of |
| 7162 | (concat | 7159 | NAME is unquoted." |
| 7163 | (file-remote-p name) (file-name-unquote-non-special (file-local-name name)))) | 7160 | (let* ((file-name-handler-alist (unless top file-name-handler-alist)) |
| 7161 | (localname (file-local-name name))) | ||
| 7162 | (when (file-name-quoted-p localname top) | ||
| 7163 | (setq | ||
| 7164 | localname (if (= (length localname) 2) "/" (substring localname 2)))) | ||
| 7165 | (concat (file-remote-p name) localname))) | ||
| 7164 | 7166 | ||
| 7165 | ;; Symbolic modes and read-file-modes. | 7167 | ;; Symbolic modes and read-file-modes. |
| 7166 | 7168 | ||