mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-24 07:20:37 +00:00
Implement quoting the local part of a remote file name
* doc/emacs/files.texi (Quoted File Names): * etc/NEWS: Mention quoting the local part of a remote file name. * lisp/net/tramp.el (tramp-dissect-file-name): Check with `tramp-tramp-file-p'. (tramp-quoted-name-p, tramp-quote-name, tramp-unquote-name): New defsubst. (tramp-handle-substitute-in-file-name) (tramp-handle-make-auto-save-file-name): Handle quoted files. (tramp-shell-quote-argument): Unquote argument. * lisp/net/tramp-sh.el (tramp-sh-handle-file-truename): Handle quoted files. * test/lisp/net/tramp-tests.el (tramp--test-expensive-test): New defvar. (tramp--test-make-temp-name): New argument QUOTED. (tramp-test01-file-name-syntax) (tramp-test02-file-name-dissect) (tramp-test04-substitute-in-file-name) (tramp-test05-expand-file-name, tramp-test07-file-exists-p) (tramp-test08-file-local-copy) (tramp-test09-insert-file-contents) (tramp-test10-write-region, tramp-test11-copy-file) (tramp-test12-rename-file, tramp-test13-make-directory) (tramp-test14-delete-directory, tramp-test15-copy-directory) (tramp-test16-directory-files) (tramp-test17-insert-directory) (tramp-test18-file-attributes) (tramp-test19-directory-files-and-attributes) (tramp-test20-file-modes, tramp-test21-file-links) (tramp-test22-file-times, tramp-test23-visited-file-modtime) (tramp-test24-file-name-completion, tramp-test25-load) (tramp-test26-process-file, tramp-test27-start-file-process) (tramp-test28-shell-command, tramp-test30-vc-registered) (tramp-test31-make-auto-save-file-name) (tramp--test-check-files) (tramp-test35-asynchronous-requests): Test also quoted file names. (tramp--test-shell-command-to-string-asynchronously): Rename. (tramp-test29-environment-variables): Use it.
This commit is contained in:
parent
35d5470962
commit
35a86f0b6f
@ -1870,6 +1870,11 @@ prevent it from being treated as a remote file name. Thus, if you have
|
||||
a directory named @file{/foo:} and a file named @file{bar} in it, you
|
||||
can refer to that file in Emacs as @samp{/:/foo:/bar}.
|
||||
|
||||
If you want to quote only special characters in the local part of a
|
||||
remote file name, you can quote just the local part.
|
||||
@samp{/baz:/:/foo:/bar} refers to the file @file{bar} of directory
|
||||
@file{/foo:} on the host @file{baz}.
|
||||
|
||||
@samp{/:} can also prevent @samp{~} from being treated as a special
|
||||
character for a user's home directory. For example, @file{/:/tmp/~hack}
|
||||
refers to a file whose name is @file{~hack} in directory @file{/tmp}.
|
||||
|
6
etc/NEWS
6
etc/NEWS
@ -268,6 +268,12 @@ variable of this kind to swap modifiers in Emacs.
|
||||
---
|
||||
** New input methods: 'cyrillic-tuvan', 'polish-prefix'.
|
||||
|
||||
+++
|
||||
** File name quoting by adding the prefix "/:" is now possible for the
|
||||
local part of a remote file name. Thus, if you have a directory named
|
||||
"/~" on the remote host "foo", you can prevent it from being
|
||||
substituted by a home directory by writing it as "/foo:/:/~/file".
|
||||
|
||||
|
||||
* Editing Changes in Emacs 26.1
|
||||
|
||||
|
@ -1146,7 +1146,9 @@ target of the symlink differ."
|
||||
(tramp-make-tramp-file-name
|
||||
method user host
|
||||
(with-tramp-file-property v localname "file-truename"
|
||||
(let ((result nil)) ; result steps in reverse order
|
||||
(let ((result nil) ; result steps in reverse order
|
||||
(quoted (tramp-quoted-name-p localname))
|
||||
(localname (tramp-unquote-name localname)))
|
||||
(tramp-message v 4 "Finding true name for `%s'" filename)
|
||||
(cond
|
||||
;; Use GNU readlink --canonicalize-missing where available.
|
||||
@ -1241,6 +1243,7 @@ target of the symlink differ."
|
||||
(when (string= "" result)
|
||||
(setq result "/")))))
|
||||
|
||||
(when quoted (setq result (tramp-quote-name result)))
|
||||
(tramp-message v 4 "True name of `%s' is `%s'" localname result)
|
||||
result))))
|
||||
|
||||
|
@ -1239,9 +1239,9 @@ localname (file name on remote host) and hop. If NODEFAULT is
|
||||
non-nil, the file name parts are not expanded to their default
|
||||
values."
|
||||
(save-match-data
|
||||
(unless (tramp-tramp-file-p name)
|
||||
(tramp-compat-user-error nil "Not a Tramp file name: \"%s\"" name))
|
||||
(let ((match (string-match (nth 0 tramp-file-name-structure) name)))
|
||||
(unless match
|
||||
(tramp-compat-user-error nil "Not a Tramp file name: \"%s\"" name))
|
||||
(let ((method (match-string (nth 1 tramp-file-name-structure) name))
|
||||
(user (match-string (nth 2 tramp-file-name-structure) name))
|
||||
(host (match-string (nth 3 tramp-file-name-structure) name))
|
||||
@ -1679,6 +1679,27 @@ FILE must be a local file name on a connection identified via VEC."
|
||||
(font-lock-add-keywords
|
||||
'emacs-lisp-mode '("\\<with-tramp-connection-property\\>"))
|
||||
|
||||
(defsubst tramp-quoted-name-p (name)
|
||||
"Whether NAME is quoted with prefix \"/:\".
|
||||
If NAME is a remote file name, check the local part of NAME."
|
||||
(string-match "^/:" (or (file-remote-p name 'localname) name)))
|
||||
|
||||
(defsubst tramp-quote-name (name)
|
||||
"Add the quotation prefix \"/:\" to file NAME.
|
||||
If NAME is a remote file name, the local part of NAME is quoted."
|
||||
(concat (file-remote-p name) "/:" (or (file-remote-p name 'localname) name)))
|
||||
|
||||
(defsubst tramp-unquote-name (name)
|
||||
"Remove quotation prefix \"/:\" from file NAME.
|
||||
If NAME is a remote file name, the local part of NAME is unquoted."
|
||||
(save-match-data
|
||||
(let ((localname (or (file-remote-p name 'localname) name)))
|
||||
(when (tramp-quoted-name-p localname)
|
||||
(setq
|
||||
localname
|
||||
(replace-match (if (= (length localname) 2) "/" "") nil t localname)))
|
||||
(concat (file-remote-p name) localname))))
|
||||
|
||||
(defun tramp-drop-volume-letter (name)
|
||||
"Cut off unnecessary drive letter from file NAME.
|
||||
The functions `tramp-*-handle-expand-file-name' call `expand-file-name'
|
||||
@ -3323,20 +3344,23 @@ User is always nil."
|
||||
(defun tramp-handle-substitute-in-file-name (filename)
|
||||
"Like `substitute-in-file-name' for Tramp files.
|
||||
\"//\" and \"/~\" substitute only in the local filename part."
|
||||
;; First, we must replace environment variables.
|
||||
(setq filename (tramp-replace-environment-variables filename))
|
||||
(with-parsed-tramp-file-name filename nil
|
||||
;; Ignore in LOCALNAME everything before "//" or "/~".
|
||||
(when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname))
|
||||
(setq filename
|
||||
(concat (file-remote-p filename)
|
||||
(replace-match "\\1" nil nil localname)))
|
||||
;; "/m:h:~" does not work for completion. We use "/m:h:~/".
|
||||
(when (string-match "~$" filename)
|
||||
(setq filename (concat filename "/"))))
|
||||
;; We do not want to replace environment variables, again.
|
||||
(let (process-environment)
|
||||
(tramp-run-real-handler 'substitute-in-file-name (list filename)))))
|
||||
;; Check, whether the local part is a quoted file name.
|
||||
(if (tramp-quoted-name-p filename)
|
||||
filename
|
||||
;; First, we must replace environment variables.
|
||||
(setq filename (tramp-replace-environment-variables filename))
|
||||
(with-parsed-tramp-file-name filename nil
|
||||
;; Ignore in LOCALNAME everything before "//" or "/~".
|
||||
(when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname))
|
||||
(setq filename
|
||||
(concat (file-remote-p filename)
|
||||
(replace-match "\\1" nil nil localname)))
|
||||
;; "/m:h:~" does not work for completion. We use "/m:h:~/".
|
||||
(when (string-match "~$" filename)
|
||||
(setq filename (concat filename "/"))))
|
||||
;; We do not want to replace environment variables, again.
|
||||
(let (process-environment)
|
||||
(tramp-run-real-handler 'substitute-in-file-name (list filename))))))
|
||||
|
||||
(defun tramp-handle-set-visited-file-modtime (&optional time-list)
|
||||
"Like `set-visited-file-modtime' for Tramp files."
|
||||
@ -4080,7 +4104,7 @@ this file, if that variable is non-nil."
|
||||
("|" . "__")
|
||||
("[" . "_l")
|
||||
("]" . "_r"))
|
||||
(buffer-file-name))
|
||||
(tramp-unquote-name (buffer-file-name)))
|
||||
tramp-auto-save-directory))))
|
||||
;; Run plain `make-auto-save-file-name'.
|
||||
(tramp-run-real-handler 'make-auto-save-file-name nil)))
|
||||
@ -4318,7 +4342,7 @@ T1 and T2 are time values (as returned by `current-time' for example)."
|
||||
Only works for Bourne-like shells."
|
||||
(let ((system-type 'not-windows))
|
||||
(save-match-data
|
||||
(let ((result (shell-quote-argument s))
|
||||
(let ((result (shell-quote-argument (tramp-unquote-name s)))
|
||||
(nl (regexp-quote (format "\\%s" tramp-rsh-end-of-line))))
|
||||
(when (and (>= (length result) 2)
|
||||
(string= (substring result 0 2) "\\~"))
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user