diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index e189da9fbe2..d9e366be1ba 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2546,14 +2546,7 @@ that remote host. If such a directory does not exist, or @end defun In order to extract the local part of the path name from a temporary -file, the following code could be used: - -@example -@group -(let ((tmpfile (make-nearby-temp-file "foo"))) - (or (file-remote-p tmpfile 'localname) tmpfile)) -@end group -@end example +file, @code{file-local-name} could be used. @node File Name Completion @subsection File Name Completion @@ -3233,6 +3226,13 @@ non-magic directory to serve as its current directory, and this function is a good way to come up with one. @end defun +@defun file-local-name filename +This function returns the local part of file @var{filename}. For a +remote @var{filename}, it returns a file name which could be used +directly as argument of a remote process. If @var{filename} is local, +this function returns the file name. +@end defun + @defopt remote-file-name-inhibit-cache The attributes of remote files can be cached for better performance. If they are changed outside of Emacs's control, the cached values become diff --git a/etc/NEWS b/etc/NEWS index 21cda7c6b0a..619d56ba7b7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -699,6 +699,10 @@ collection). ** The new functions 'make-nearby-temp-file' and 'temporary-file-directory' can be used for creation of temporary files of remote or mounted directories. ++++ +** The new function 'file-local-name' can be used to specify arguments +of remote processes. + +++ ** The new error 'file-missing', a subcategory of 'file-error', is now signaled instead of 'file-error' if a file operation acts on a file diff --git a/lisp/eshell/em-tramp.el b/lisp/eshell/em-tramp.el index 9105c482b38..3eff20d1a1b 100644 --- a/lisp/eshell/em-tramp.el +++ b/lisp/eshell/em-tramp.el @@ -72,8 +72,7 @@ Become another USER during a login session.") (let ((user "root") (host (or (file-remote-p default-directory 'host) "localhost")) - (dir (or (file-remote-p default-directory 'localname) - (expand-file-name default-directory))) + (dir (file-local-name (expand-file-name default-directory))) (prefix (file-remote-p default-directory))) (dolist (arg args) (if (string-equal arg "-") (setq login t) (setq user arg))) @@ -111,8 +110,7 @@ Execute a COMMAND as the superuser or another USER.") (let ((user (or user "root")) (host (or (file-remote-p default-directory 'host) "localhost")) - (dir (or (file-remote-p default-directory 'localname) - (expand-file-name default-directory))) + (dir (file-local-name (expand-file-name default-directory))) (prefix (file-remote-p default-directory))) ;; `eshell-eval-using-options' reads options of COMMAND. (while (and (stringp (car orig-args)) diff --git a/lisp/eshell/esh-ext.el b/lisp/eshell/esh-ext.el index ca62d0cf8b0..4d658cd718e 100644 --- a/lisp/eshell/esh-ext.el +++ b/lisp/eshell/esh-ext.el @@ -203,7 +203,7 @@ all the output from the remote command, and sends it all at once, causing the user to wonder if anything's really going on..." (let ((outbuf (generate-new-buffer " *eshell remote output*")) (errbuf (generate-new-buffer " *eshell remote error*")) - (command (or (file-remote-p command 'localname) command)) + (command (file-local-name command)) (exitcode 1)) (unwind-protect (progn diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 8c6bad089c5..21680df765d 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -279,7 +279,7 @@ See `eshell-needs-pipe'." (let ((process-connection-type (unless (eshell-needs-pipe-p command) process-connection-type)) - (command (or (file-remote-p command 'localname) command))) + (command (file-local-name command))) (apply 'start-file-process (file-name-nondirectory command) nil ;; `start-process' can't deal with relative filenames. diff --git a/lisp/files.el b/lisp/files.el index c50e6aa4146..7c56f54a463 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1128,6 +1128,12 @@ consecutive checks. For example: :format "Do not use file name cache older then %v seconds" :value 10))) +(defun file-local-name (file) + "Return the local name component of FILE. +It returns a file name which can be used directly as argument of +`process-file', `start-file-process', or `shell-command'." + (or (file-remote-p file 'localname) file)) + (defun file-local-copy (file) "Copy the file FILE into a temporary file on this machine. Returns the name of the local copy, or nil, if FILE is directly @@ -6212,9 +6218,7 @@ default directory. However, if FULL is non-nil, they are absolute." ;; This can be more than one dir ;; if DIRPART contains wildcards. (dirs (if (and dirpart - (string-match "[[*?]" - (or (file-remote-p dirpart 'localname) - dirpart))) + (string-match "[[*?]" (file-local-name dirpart))) (mapcar 'file-name-as-directory (file-expand-wildcards (directory-file-name dirpart))) (list dirpart))) diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el index e3d778f73b4..c76d276369f 100644 --- a/lisp/org/ob-core.el +++ b/lisp/org/ob-core.el @@ -2680,9 +2680,12 @@ Fixes a bug in `tramp-handle-call-process-region'." (apply org-babel-call-process-region-original start end program delete buffer display args))) -(defun org-babel-local-file-name (file) - "Return the local name component of FILE." - (or (file-remote-p file 'localname) file)) +(defalias 'org-babel-local-file-name + (if (fboundp 'file-local-name) + 'file-local-name + (lambda (file) + "Return the local name component of FILE." + (or (file-remote-p file 'localname) file)))) (defun org-babel-process-file-name (name &optional no-quote-p) "Prepare NAME to be used in an external process. diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index 9052aa40358..0bdafdbac6e 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el @@ -2621,12 +2621,8 @@ comint mode, which see." (let ((w args)) (while (and w (not (eq (car w) t))) (setq w (cdr w))) - (if w - (setcar w - (if (file-remote-p file) - ;; Tramp has already been loaded if we are here. - (setq file (file-remote-p file 'localname)) - file)))) + ;; Tramp has already been loaded if we are here. + (if w (setcar w (setq file (file-local-name file))))) (apply 'make-comint (concat "gud" filepart) program nil (if massage-args (funcall massage-args file args) args)) ;; Since comint clobbered the mode, we don't set it until now. @@ -2854,8 +2850,7 @@ Obeying it means displaying in another window the specified file and line." (frame (or gud-last-frame gud-last-last-frame)) (buffer-file-name-localized (and (buffer-file-name) - (or (file-remote-p (buffer-file-name) 'localname) - (buffer-file-name)))) + (file-local-name (buffer-file-name)))) result) (while (and str (let ((case-fold-search nil)) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index be96ac32a01..af8b791a90e 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -3150,13 +3150,10 @@ t when called interactively." (insert-file-contents (or temp-file-name file-name)) (python-info-encoding))) - (file-name (expand-file-name - (or (file-remote-p file-name 'localname) - file-name))) + (file-name (expand-file-name (file-local-name file-name))) (temp-file-name (when temp-file-name (expand-file-name - (or (file-remote-p temp-file-name 'localname) - temp-file-name))))) + (file-local-name temp-file-name))))) (python-shell-send-string (format (concat diff --git a/lisp/shell.el b/lisp/shell.el index 34bd77282ab..d1b2e875746 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -714,12 +714,11 @@ Otherwise, one argument `-i' is passed to the shell. (null (getenv "ESHELL"))) (with-current-buffer buffer (set (make-local-variable 'explicit-shell-file-name) - (file-remote-p - (expand-file-name + (expand-file-name + (file-local-name (read-file-name "Remote shell path: " default-directory shell-file-name - t shell-file-name)) - 'localname)))) + t shell-file-name)))))) ;; The buffer's window must be correctly set when we call comint (so ;; that comint sets the COLUMNS env var properly). diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el index b1ac32d7019..56bfebb579c 100644 --- a/lisp/vc/ediff-diff.el +++ b/lisp/vc/ediff-diff.el @@ -1347,10 +1347,8 @@ arguments to `skip-chars-forward'." ;; located on the same remote host. (apply 'process-file ediff-cmp-program nil nil nil (append ediff-cmp-options - (list (or (file-remote-p f1 'localname) - (expand-file-name f1)) - (or (file-remote-p f2 'localname) - (expand-file-name f2))))) + (list (expand-file-name (file-local-name f1)) + (expand-file-name (file-local-name f2))))) )) (and (numberp res) (eq res 0))) diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 9df581dda5b..ec0e081743d 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -704,13 +704,10 @@ It is based on `log-edit-mode', and has Git-specific extensions.") ;; file, to work around the limitation that command-line ;; arguments must be in the system codepage, and therefore ;; might not support the non-ASCII characters in the log - ;; message. + ;; message. Handle also remote files. (if (eq system-type 'windows-nt) - (if (file-remote-p file1) - (let ((default-directory (file-name-directory file1))) - (file-remote-p - (make-nearby-temp-file "git-msg") 'localname)) - (make-temp-file "git-msg"))))) + (let ((default-directory (file-name-directory file1))) + (file-local-name (make-nearby-temp-file "git-msg")))))) (cl-flet ((boolean-arg-fn (argument) (lambda (value) (when (equal value "yes") (list argument)))))