aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMichael Albinus2018-06-20 12:13:56 +0200
committerMichael Albinus2018-06-20 12:13:56 +0200
commit6f649e77b8512f73b17f03fd795beea9965c4029 (patch)
treec52a6a8413dab1e9af36d975869f16019230ad53 /lisp
parent3a47f3921bdaaf7b7d80dc3be05a5f1b1f2501eb (diff)
downloademacs-6f649e77b8512f73b17f03fd795beea9965c4029.tar.gz
emacs-6f649e77b8512f73b17f03fd795beea9965c4029.zip
Implement command completion in remote shells. (Bug#31704)
* doc/lispref/files.texi (Locating Files): Describe optional argument REMOTE of `executable-find'. (Magic File Names): Add `exec-path'. * doc/lispref/processes.texi (Subprocess Creation): Describe function `exec-path'. * doc/misc/tramp.texi (Remote programs): Explain refresh of search paths by `tramp-cleanup-this-connection'. * etc/NEWS: Mention 'exec-path' and 'executable-find'. * lisp/files.el (exec-path): New defun. (executable-find): Add optional argument REMOTE. * lisp/shell.el (shell-completion-vars): Set `comint-file-name-prefix'. (shell--command-completion-data): Use `(exec-path)'. (Bug#31704) * lisp/net/ange-ftp.el (exec-path): * lisp/net/tramp.el (tramp-file-name-for-operation): * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist): * lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist): * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist): * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist): * lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist) <exec-path>: Add handler. * lisp/net/tramp-adb.el (tramp-adb-handle-exec-path): New defun. (tramp-adb-maybe-open-connection): Do not set "remote-path" connection property. * lisp/net/tramp-compat.el (tramp-compat-exec-path): New defun. * lisp/net/tramp-sh.el (tramp-sh-handle-exec-path): New defun. * lisp/net/tramp.el (tramp-eshell-directory-change): Use it. * test/lisp/net/tramp-archive-tests.el (tramp-archive-test38-make-nearby-temp-file) (tramp-archive-test41-file-system-info) (tramp-archive-test43-auto-load) (tramp-archive-test43-delay-load): Rename. * test/lisp/net/tramp-tests.el (tramp-test34-exec-path): New test. (tramp-test36-make-auto-save-file-name) (tramp-test37-find-backup-file-name) (tramp-test38-make-nearby-temp-file) (tramp-test39-special-characters) (tramp-test39-special-characters-with-stat) (tramp-test39-special-characters-with-perl) (tramp-test39-special-characters-with-ls, tramp-test40-utf8) (tramp-test40-utf8-with-stat, tramp-test40-utf8-with-perl) (tramp-test40-utf8-with-ls, tramp-test41-file-system-info) (tramp-test42-asynchronous-requests, tramp-test43-auto-load) (tramp-test43-delay-load, tramp-test43-recursive-load) (tramp-test43-remote-load-path, tramp-test44-unload): Rename.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/files.el30
-rw-r--r--lisp/net/ange-ftp.el1
-rw-r--r--lisp/net/tramp-adb.el28
-rw-r--r--lisp/net/tramp-archive.el1
-rw-r--r--lisp/net/tramp-compat.el11
-rw-r--r--lisp/net/tramp-gvfs.el1
-rw-r--r--lisp/net/tramp-sh.el8
-rw-r--r--lisp/net/tramp-smb.el1
-rw-r--r--lisp/net/tramp.el18
-rw-r--r--lisp/shell.el11
10 files changed, 77 insertions, 33 deletions
diff --git a/lisp/files.el b/lisp/files.el
index c4a68d04407..d0804b000a6 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1024,13 +1024,33 @@ customize the variable `user-emacs-directory-warning'."
1024 errtype user-emacs-directory))))) 1024 errtype user-emacs-directory)))))
1025 bestname)))) 1025 bestname))))
1026 1026
1027(defun exec-path ()
1028 "List of directories to search programs to run in remote subprocesses.
1029The remote host is identified by `default-directory'. For remote
1030hosts which do not support subprocesses, this returns `nil'.
1031If `default-directory' is a local directory, the value of the variable
1032`exec-path' is returned."
1033 (let ((handler (find-file-name-handler default-directory 'exec-path)))
1034 (if handler
1035 (funcall handler 'exec-path)
1036 exec-path)))
1027 1037
1028(defun executable-find (command) 1038(defun executable-find (command &optional remote)
1029 "Search for COMMAND in `exec-path' and return the absolute file name. 1039 "Search for COMMAND in `exec-path' and return the absolute file name.
1030Return nil if COMMAND is not found anywhere in `exec-path'." 1040Return nil if COMMAND is not found anywhere in `exec-path'. If
1031 ;; Use 1 rather than file-executable-p to better match the behavior of 1041REMOTE is non-nil, search on the remote host indicated by
1032 ;; call-process. 1042`default-directory' instead."
1033 (locate-file command exec-path exec-suffixes 1)) 1043 (if (and remote (file-remote-p default-directory))
1044 (let ((res (locate-file
1045 command
1046 (mapcar
1047 (lambda (x) (concat (file-remote-p default-directory) x))
1048 (exec-path))
1049 exec-suffixes 'file-executable-p)))
1050 (when (stringp res) (file-local-name res)))
1051 ;; Use 1 rather than file-executable-p to better match the
1052 ;; behavior of call-process.
1053 (locate-file command exec-path exec-suffixes 1)))
1034 1054
1035(defun load-library (library) 1055(defun load-library (library)
1036 "Load the Emacs Lisp library named LIBRARY. 1056 "Load the Emacs Lisp library named LIBRARY.
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index cf9667ac628..2fc7ac251ec 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -4439,6 +4439,7 @@ NEWNAME should be the name to give the new compressed or uncompressed file.")
4439(put 'process-file 'ange-ftp 'ange-ftp-process-file) 4439(put 'process-file 'ange-ftp 'ange-ftp-process-file)
4440(put 'start-file-process 'ange-ftp 'ignore) 4440(put 'start-file-process 'ange-ftp 'ignore)
4441(put 'shell-command 'ange-ftp 'ange-ftp-shell-command) 4441(put 'shell-command 'ange-ftp 'ange-ftp-shell-command)
4442(put 'exec-path 'ange-ftp 'ignore)
4442 4443
4443;;; Define ways of getting at unmodified Emacs primitives, 4444;;; Define ways of getting at unmodified Emacs primitives,
4444;;; turning off our handler. 4445;;; turning off our handler.
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index df2160770b1..7cb61adde80 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -107,6 +107,7 @@ It is used for TCP/IP devices."
107 . tramp-adb-handle-directory-files-and-attributes) 107 . tramp-adb-handle-directory-files-and-attributes)
108 (dired-compress-file . ignore) 108 (dired-compress-file . ignore)
109 (dired-uncache . tramp-handle-dired-uncache) 109 (dired-uncache . tramp-handle-dired-uncache)
110 (exec-path . tramp-adb-handle-exec-path)
110 (expand-file-name . tramp-adb-handle-expand-file-name) 111 (expand-file-name . tramp-adb-handle-expand-file-name)
111 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) 112 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
112 (file-acl . ignore) 113 (file-acl . ignore)
@@ -1116,6 +1117,21 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
1116 (tramp-flush-connection-property v "process-name") 1117 (tramp-flush-connection-property v "process-name")
1117 (tramp-flush-connection-property v "process-buffer")))))) 1118 (tramp-flush-connection-property v "process-buffer"))))))
1118 1119
1120(defun tramp-adb-handle-exec-path ()
1121 "Like `exec-path' for Tramp files."
1122 (append
1123 (with-parsed-tramp-file-name default-directory nil
1124 (with-tramp-connection-property v "remote-path"
1125 (tramp-adb-send-command v "echo \\\"$PATH\\\"")
1126 (split-string
1127 (with-current-buffer (tramp-get-connection-buffer v)
1128 ;; Read the expression.
1129 (goto-char (point-min))
1130 (read (current-buffer)))
1131 ":" 'omit)))
1132 ;; The equivalent to `exec-directory'.
1133 `(,(file-local-name default-directory))))
1134
1119(defun tramp-adb-get-device (vec) 1135(defun tramp-adb-get-device (vec)
1120 "Return full host name from VEC to be used in shell execution. 1136 "Return full host name from VEC to be used in shell execution.
1121E.g. a host name \"192.168.1.1#5555\" returns \"192.168.1.1:5555\" 1137E.g. a host name \"192.168.1.1#5555\" returns \"192.168.1.1:5555\"
@@ -1340,18 +1356,6 @@ connection if a previous connection has died for some reason."
1340 (tramp-error 1356 (tramp-error
1341 vec 'file-error "Cannot switch to user `%s'" user))) 1357 vec 'file-error "Cannot switch to user `%s'" user)))
1342 1358
1343 ;; Set "remote-path" connection property. This is needed
1344 ;; for eshell.
1345 (tramp-adb-send-command vec "echo \\\"$PATH\\\"")
1346 (tramp-set-connection-property
1347 vec "remote-path"
1348 (split-string
1349 (with-current-buffer (tramp-get-connection-buffer vec)
1350 ;; Read the expression.
1351 (goto-char (point-min))
1352 (read (current-buffer)))
1353 ":" 'omit))
1354
1355 ;; Set connection-local variables. 1359 ;; Set connection-local variables.
1356 (tramp-set-connection-local-variables vec) 1360 (tramp-set-connection-local-variables vec)
1357 1361
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 42c3d40c1bb..5d7562f707e 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -220,6 +220,7 @@ It must be supported by libarchive(3).")
220 . tramp-handle-directory-files-and-attributes) 220 . tramp-handle-directory-files-and-attributes)
221 (dired-compress-file . tramp-archive-handle-not-implemented) 221 (dired-compress-file . tramp-archive-handle-not-implemented)
222 (dired-uncache . tramp-archive-handle-dired-uncache) 222 (dired-uncache . tramp-archive-handle-dired-uncache)
223 (exec-path . ignore)
223 ;; `expand-file-name' performed by default handler. 224 ;; `expand-file-name' performed by default handler.
224 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) 225 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
225 (file-acl . ignore) 226 (file-acl . ignore)
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index aa0c99bf9cf..9af57fb0755 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -236,6 +236,17 @@ If NAME is a remote file name, the local part of NAME is unquoted."
236(defconst tramp-compat-use-url-tramp-p (fboundp 'temporary-file-directory) 236(defconst tramp-compat-use-url-tramp-p (fboundp 'temporary-file-directory)
237 "Whether to use url-tramp.el.") 237 "Whether to use url-tramp.el.")
238 238
239;; `exec-path' is new in Emacs 27.1.
240(eval-and-compile
241 (if (fboundp 'exec-path)
242 (defalias 'tramp-compat-exec-path 'exec-path)
243 (defun tramp-compat-exec-path ()
244 "List of directories to search programs to run in remote subprocesses."
245 (let ((handler (find-file-name-handler default-directory 'exec-path)))
246 (if handler
247 (funcall handler 'exec-path)
248 exec-path)))))
249
239(add-hook 'tramp-unload-hook 250(add-hook 'tramp-unload-hook
240 (lambda () 251 (lambda ()
241 (unload-feature 'tramp-loaddefs 'force) 252 (unload-feature 'tramp-loaddefs 'force)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 87c0c796b69..a30d7ef7138 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -536,6 +536,7 @@ It has been changed in GVFS 1.14.")
536 . tramp-handle-directory-files-and-attributes) 536 . tramp-handle-directory-files-and-attributes)
537 (dired-compress-file . ignore) 537 (dired-compress-file . ignore)
538 (dired-uncache . tramp-handle-dired-uncache) 538 (dired-uncache . tramp-handle-dired-uncache)
539 (exec-path . ignore)
539 (expand-file-name . tramp-gvfs-handle-expand-file-name) 540 (expand-file-name . tramp-gvfs-handle-expand-file-name)
540 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) 541 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
541 (file-acl . ignore) 542 (file-acl . ignore)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 76dae9cea5e..0b3c12333f2 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -990,6 +990,7 @@ of command line.")
990 . tramp-sh-handle-directory-files-and-attributes) 990 . tramp-sh-handle-directory-files-and-attributes)
991 (dired-compress-file . tramp-sh-handle-dired-compress-file) 991 (dired-compress-file . tramp-sh-handle-dired-compress-file)
992 (dired-uncache . tramp-handle-dired-uncache) 992 (dired-uncache . tramp-handle-dired-uncache)
993 (exec-path . tramp-sh-handle-exec-path)
993 (expand-file-name . tramp-sh-handle-expand-file-name) 994 (expand-file-name . tramp-sh-handle-expand-file-name)
994 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) 995 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
995 (file-acl . tramp-sh-handle-file-acl) 996 (file-acl . tramp-sh-handle-file-acl)
@@ -3083,6 +3084,13 @@ the result will be a local, non-Tramp, file name."
3083 (keyboard-quit) 3084 (keyboard-quit)
3084 ret)))) 3085 ret))))
3085 3086
3087(defun tramp-sh-handle-exec-path ()
3088 "Like `exec-path' for Tramp files."
3089 (append
3090 (tramp-get-remote-path (tramp-dissect-file-name default-directory))
3091 ;; The equivalent to `exec-directory'.
3092 `(,(file-local-name default-directory))))
3093
3086(defun tramp-sh-handle-file-local-copy (filename) 3094(defun tramp-sh-handle-file-local-copy (filename)
3087 "Like `file-local-copy' for Tramp files." 3095 "Like `file-local-copy' for Tramp files."
3088 (with-parsed-tramp-file-name filename nil 3096 (with-parsed-tramp-file-name filename nil
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 0334f052a07..335f05cfce0 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -229,6 +229,7 @@ See `tramp-actions-before-shell' for more info.")
229 . tramp-handle-directory-files-and-attributes) 229 . tramp-handle-directory-files-and-attributes)
230 (dired-compress-file . ignore) 230 (dired-compress-file . ignore)
231 (dired-uncache . tramp-handle-dired-uncache) 231 (dired-uncache . tramp-handle-dired-uncache)
232 (exec-path . ignore)
232 (expand-file-name . tramp-smb-handle-expand-file-name) 233 (expand-file-name . tramp-smb-handle-expand-file-name)
233 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p) 234 (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
234 (file-acl . tramp-smb-handle-file-acl) 235 (file-acl . tramp-smb-handle-file-acl)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 1d6e0146c4d..d56b09a604d 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2163,7 +2163,9 @@ ARGS are the arguments OPERATION has been called with."
2163 ((member operation 2163 ((member operation
2164 '(process-file shell-command start-file-process 2164 '(process-file shell-command start-file-process
2165 ;; Emacs 26+ only. 2165 ;; Emacs 26+ only.
2166 make-nearby-temp-file temporary-file-directory)) 2166 make-nearby-temp-file temporary-file-directory
2167 ;; Emacs 27+ only.
2168 exec-path))
2167 default-directory) 2169 default-directory)
2168 ;; PROC. 2170 ;; PROC.
2169 ((member operation 2171 ((member operation
@@ -4616,19 +4618,9 @@ Only works for Bourne-like shells."
4616;; when `default-directory' points to another host. 4618;; when `default-directory' points to another host.
4617(defun tramp-eshell-directory-change () 4619(defun tramp-eshell-directory-change ()
4618 "Set `eshell-path-env' to $PATH of the host related to `default-directory'." 4620 "Set `eshell-path-env' to $PATH of the host related to `default-directory'."
4621 ;; Remove last element of `(exec-path)', which is `exec-directory'.
4619 (setq eshell-path-env 4622 (setq eshell-path-env
4620 (if (tramp-tramp-file-p default-directory) 4623 (mapconcat 'identity (butlast (tramp-compat-exec-path)) ":")))
4621 (with-parsed-tramp-file-name default-directory nil
4622 (mapconcat
4623 'identity
4624 (or
4625 ;; When `tramp-own-remote-path' is in `tramp-remote-path',
4626 ;; the remote path is only set in the session cache.
4627 (tramp-get-connection-property
4628 (tramp-get-connection-process v) "remote-path" nil)
4629 (tramp-get-connection-property v "remote-path" nil))
4630 ":"))
4631 (getenv "PATH"))))
4632 4624
4633(eval-after-load "esh-util" 4625(eval-after-load "esh-util"
4634 '(progn 4626 '(progn
diff --git a/lisp/shell.el b/lisp/shell.el
index 232186083d5..91c65ed171e 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -468,6 +468,8 @@ Shell buffers. It implements `shell-completion-execonly' for
468 (set (make-local-variable 'comint-file-name-chars) shell-file-name-chars) 468 (set (make-local-variable 'comint-file-name-chars) shell-file-name-chars)
469 (set (make-local-variable 'comint-file-name-quote-list) 469 (set (make-local-variable 'comint-file-name-quote-list)
470 shell-file-name-quote-list) 470 shell-file-name-quote-list)
471 (set (make-local-variable 'comint-file-name-prefix)
472 (file-remote-p default-directory))
471 (set (make-local-variable 'comint-dynamic-complete-functions) 473 (set (make-local-variable 'comint-dynamic-complete-functions)
472 shell-dynamic-complete-functions) 474 shell-dynamic-complete-functions)
473 (setq-local comint-unquote-function #'shell--unquote-argument) 475 (setq-local comint-unquote-function #'shell--unquote-argument)
@@ -1170,9 +1172,12 @@ Returns t if successful."
1170 (start (if (zerop (length filename)) (point) (match-beginning 0))) 1172 (start (if (zerop (length filename)) (point) (match-beginning 0)))
1171 (end (if (zerop (length filename)) (point) (match-end 0))) 1173 (end (if (zerop (length filename)) (point) (match-end 0)))
1172 (filenondir (file-name-nondirectory filename)) 1174 (filenondir (file-name-nondirectory filename))
1173 ; why cdr? see `shell-dynamic-complete-command' 1175 (path-dirs
1174 (path-dirs (append (cdr (reverse exec-path)) 1176 ;; Ignore `exec-directory', the last entry in `exec-path'.
1175 (if (memq system-type '(windows-nt ms-dos)) '(".")))) 1177 (append (cdr (reverse (exec-path)))
1178 (if (and (memq system-type '(windows-nt ms-dos))
1179 (not (file-remote-p default-directory)))
1180 '("."))))
1176 (cwd (file-name-as-directory (expand-file-name default-directory))) 1181 (cwd (file-name-as-directory (expand-file-name default-directory)))
1177 (ignored-extensions 1182 (ignored-extensions
1178 (and comint-completion-fignore 1183 (and comint-completion-fignore