aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2009-11-24 10:25:54 +0000
committerMichael Albinus2009-11-24 10:25:54 +0000
commit605a20a98823768578d6faed5f04cb00e57da2bb (patch)
tree525322a2fc9fbabb9d8bebc014e51d061aeff7c2
parent937e60c88bfbbc44d44806a7cf43d5f982a8026f (diff)
downloademacs-605a20a98823768578d6faed5f04cb00e57da2bb.tar.gz
emacs-605a20a98823768578d6faed5f04cb00e57da2bb.zip
Improve handling of processes on remote hosts.
* eshell/esh-util.el (eshell-path-env): New defvar. (eshell-parse-colon-path): New defun. (eshell-file-attributes): Use `eshell-parse-colon-path'. * eshell/esh-ext.el (eshell-search-path): Use `eshell-parse-colon-path'. (eshell-remote-command): Remove argument HANDLER. (eshell-external-command): Check for FTP remote connection. * eshell/esh-proc.el (eshell-gather-process-output): Use `file-truename', in order to start also symlinked files. Apply `start-file-process' instead of `start-process'. Shorten `command' to the local file name part. * eshell/em-cmpl.el (eshell-complete-commands-list): Use `eshell-parse-colon-path'. * eshell/em-unix.el (eshell/du): Check for FTP remote connection. * net/tramp.el (tramp-eshell-directory-change): New defun. Add it to `eshell-directory-change-hook'.
-rw-r--r--lisp/ChangeLog26
-rw-r--r--lisp/eshell/em-cmpl.el2
-rw-r--r--lisp/eshell/em-unix.el5
-rw-r--r--lisp/eshell/esh-ext.el37
-rw-r--r--lisp/eshell/esh-proc.el9
-rw-r--r--lisp/eshell/esh-util.el52
-rw-r--r--lisp/net/tramp.el29
7 files changed, 108 insertions, 52 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 054ff8d268b..03fdcf9a1bc 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,29 @@
12009-11-24 Michael Albinus <michael.albinus@gmx.de>
2
3 Improve handling of processes on remote hosts.
4
5 * eshell/esh-util.el (eshell-path-env): New defvar.
6 (eshell-parse-colon-path): New defun.
7 (eshell-file-attributes): Use `eshell-parse-colon-path'.
8
9 * eshell/esh-ext.el (eshell-search-path): Use
10 `eshell-parse-colon-path'.
11 (eshell-remote-command): Remove argument HANDLER.
12 (eshell-external-command): Check for FTP remote connection.
13
14 * eshell/esh-proc.el (eshell-gather-process-output): Use
15 `file-truename', in order to start also symlinked files. Apply
16 `start-file-process' instead of `start-process'. Shorten `command'
17 to the local file name part.
18
19 * eshell/em-cmpl.el (eshell-complete-commands-list): Use
20 `eshell-parse-colon-path'.
21
22 * eshell/em-unix.el (eshell/du): Check for FTP remote connection.
23
24 * net/tramp.el (tramp-eshell-directory-change): New defun. Add it
25 to `eshell-directory-change-hook'.
26
12009-11-24 Tassilo Horn <tassilo@member.fsf.org> 272009-11-24 Tassilo Horn <tassilo@member.fsf.org>
2 28
3 * doc-view.el (doc-view-mode): Switch off view-mode explicitly, 29 * doc-view.el (doc-view-mode): Switch off view-mode explicitly,
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index 8e650ce16ee..fbef32a1a66 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -402,7 +402,7 @@ to writing a completion function."
402 (setq filename (substring filename 1) 402 (setq filename (substring filename 1)
403 pcomplete-stub filename 403 pcomplete-stub filename
404 glob-name t)) 404 glob-name t))
405 (let* ((paths (split-string (getenv "PATH") path-separator)) 405 (let* ((paths (eshell-parse-colon-path eshell-path-env))
406 (cwd (file-name-as-directory 406 (cwd (file-name-as-directory
407 (expand-file-name default-directory))) 407 (expand-file-name default-directory)))
408 (path "") (comps-in-path ()) 408 (path "") (comps-in-path ())
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index dab1ab8f955..d6ba970b6bb 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -859,9 +859,8 @@ external command."
859 (if (and ext-du 859 (if (and ext-du
860 (not (catch 'have-ange-path 860 (not (catch 'have-ange-path
861 (eshell-for arg args 861 (eshell-for arg args
862 (if (eq (find-file-name-handler (expand-file-name arg) 862 (if (string-equal
863 'directory-files) 863 (file-remote-p (expand-file-name arg) 'method) "ftp")
864 'ange-ftp-hook-function)
865 (throw 'have-ange-path t)))))) 864 (throw 'have-ange-path t))))))
866 (throw 'eshell-replace-command 865 (throw 'eshell-replace-command
867 (eshell-parse-command ext-du args)) 866 (eshell-parse-command ext-du args))
diff --git a/lisp/eshell/esh-ext.el b/lisp/eshell/esh-ext.el
index 9fc7d86b328..f32ab7917ae 100644
--- a/lisp/eshell/esh-ext.el
+++ b/lisp/eshell/esh-ext.el
@@ -73,7 +73,7 @@ since nothing else but Eshell will be able to understand
73 "Search the environment path for NAME." 73 "Search the environment path for NAME."
74 (if (file-name-absolute-p name) 74 (if (file-name-absolute-p name)
75 name 75 name
76 (let ((list (parse-colon-path (getenv "PATH"))) 76 (let ((list (eshell-parse-colon-path eshell-path-env))
77 suffixes n1 n2 file) 77 suffixes n1 n2 file)
78 (while list 78 (while list
79 (setq n1 (concat (car list) name)) 79 (setq n1 (concat (car list) name))
@@ -176,7 +176,7 @@ This bypasses all Lisp functions and aliases."
176 (error "%s: external command not found" 176 (error "%s: external command not found"
177 (substring command 1)))))) 177 (substring command 1))))))
178 178
179(defun eshell-remote-command (handler command args) 179(defun eshell-remote-command (command args)
180 "Insert output from a remote COMMAND, using ARGS. 180 "Insert output from a remote COMMAND, using ARGS.
181A remote command is something that executes on a different machine. 181A remote command is something that executes on a different machine.
182An external command simply means external to Emacs. 182An external command simply means external to Emacs.
@@ -190,10 +190,10 @@ causing the user to wonder if anything's really going on..."
190 (unwind-protect 190 (unwind-protect
191 (progn 191 (progn
192 (setq exitcode 192 (setq exitcode
193 (funcall handler 'shell-command 193 (shell-command
194 (mapconcat 'shell-quote-argument 194 (mapconcat 'shell-quote-argument
195 (append (list command) args) " ") 195 (append (list command) args) " ")
196 outbuf errbuf)) 196 outbuf errbuf))
197 (eshell-print (with-current-buffer outbuf (buffer-string))) 197 (eshell-print (with-current-buffer outbuf (buffer-string)))
198 (eshell-error (with-current-buffer errbuf (buffer-string)))) 198 (eshell-error (with-current-buffer errbuf (buffer-string))))
199 (eshell-close-handles exitcode 'nil) 199 (eshell-close-handles exitcode 'nil)
@@ -203,23 +203,14 @@ causing the user to wonder if anything's really going on..."
203(defun eshell-external-command (command args) 203(defun eshell-external-command (command args)
204 "Insert output from an external COMMAND, using ARGS." 204 "Insert output from an external COMMAND, using ARGS."
205 (setq args (eshell-stringify-list (eshell-flatten-list args))) 205 (setq args (eshell-stringify-list (eshell-flatten-list args)))
206 (let ((handler 206 (if (string-equal (file-remote-p default-directory 'method) "ftp")
207 (unless (or (equal default-directory "/") 207 (eshell-remote-command command args))
208 (and (eshell-under-windows-p) 208 (let ((interp (eshell-find-interpreter command)))
209 (string-match "\\`[A-Za-z]:[/\\\\]\\'" 209 (assert interp)
210 default-directory))) 210 (if (functionp (car interp))
211 (find-file-name-handler default-directory 211 (apply (car interp) (append (cdr interp) args))
212 'shell-command)))) 212 (eshell-gather-process-output
213 (if (and handler 213 (car interp) (append (cdr interp) args)))))
214 (not (and (featurep 'xemacs)
215 (eq handler 'dired-handler-fn))))
216 (eshell-remote-command handler command args))
217 (let ((interp (eshell-find-interpreter command)))
218 (assert interp)
219 (if (functionp (car interp))
220 (apply (car interp) (append (cdr interp) args))
221 (eshell-gather-process-output
222 (car interp) (append (cdr interp) args))))))
223 214
224(defun eshell/addpath (&rest args) 215(defun eshell/addpath (&rest args)
225 "Add a set of paths to PATH." 216 "Add a set of paths to PATH."
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 0aa7d44190c..dac7b58dc9a 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -261,7 +261,7 @@ See `eshell-needs-pipe'."
261(defun eshell-gather-process-output (command args) 261(defun eshell-gather-process-output (command args)
262 "Gather the output from COMMAND + ARGS." 262 "Gather the output from COMMAND + ARGS."
263 (unless (and (file-executable-p command) 263 (unless (and (file-executable-p command)
264 (file-regular-p command)) 264 (file-regular-p (file-truename command)))
265 (error "%s: not an executable file" command)) 265 (error "%s: not an executable file" command))
266 (let* ((delete-exited-processes 266 (let* ((delete-exited-processes
267 (if eshell-current-subjob-p 267 (if eshell-current-subjob-p
@@ -270,12 +270,13 @@ See `eshell-needs-pipe'."
270 (process-environment (eshell-environment-variables)) 270 (process-environment (eshell-environment-variables))
271 proc decoding encoding changed) 271 proc decoding encoding changed)
272 (cond 272 (cond
273 ((fboundp 'start-process) 273 ((fboundp 'start-file-process)
274 (setq proc 274 (setq proc
275 (let ((process-connection-type 275 (let ((process-connection-type
276 (unless (eshell-needs-pipe-p command) 276 (unless (eshell-needs-pipe-p command)
277 process-connection-type))) 277 process-connection-type))
278 (apply 'start-process 278 (command (or (file-remote-p command 'localname) command)))
279 (apply 'start-file-process
279 (file-name-nondirectory command) nil 280 (file-name-nondirectory command) nil
280 ;; `start-process' can't deal with relative filenames. 281 ;; `start-process' can't deal with relative filenames.
281 (append (list (expand-file-name command)) args)))) 282 (append (list (expand-file-name command)) args))))
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 4c5ecb4617a..37802a412b5 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -237,6 +237,21 @@ If N or M is nil, it means the end of the list."
237 a (last a))) 237 a (last a)))
238 a)) 238 a))
239 239
240(defvar eshell-path-env (getenv "PATH")
241 "Content of $PATH.
242It might be different from \(getenv \"PATH\"\), when
243`default-directory' points to a remote host.")
244
245(defun eshell-parse-colon-path (path-env)
246 "Split string with `parse-colon-path'.
247Prepend remote identification of `default-directory', if any."
248 (let ((remote (file-remote-p default-directory)))
249 (if remote
250 (mapcar
251 (lambda (x) (concat remote x))
252 (parse-colon-path path-env))
253 (parse-colon-path path-env))))
254
240(defun eshell-split-path (path) 255(defun eshell-split-path (path)
241 "Split a path into multiple subparts." 256 "Split a path into multiple subparts."
242 (let ((len (length path)) 257 (let ((len (length path))
@@ -682,29 +697,24 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
682(defun eshell-file-attributes (file) 697(defun eshell-file-attributes (file)
683 "Return the attributes of FILE, playing tricks if it's over ange-ftp." 698 "Return the attributes of FILE, playing tricks if it's over ange-ftp."
684 (let* ((file (expand-file-name file)) 699 (let* ((file (expand-file-name file))
685 (handler (find-file-name-handler file 'file-attributes))
686 entry) 700 entry)
687 (if (not handler) 701 (if (string-equal (file-remote-p file 'method) "ftp")
688 (file-attributes file) 702 (let ((base (file-name-nondirectory file))
689 (if (eq (find-file-name-handler (file-name-directory file) 703 (dir (file-name-directory file)))
690 'directory-files) 704 (if (boundp 'ange-cache)
691 'ange-ftp-hook-function) 705 (setq entry (cdr (assoc base (cdr (assoc dir ange-cache))))))
692 (let ((base (file-name-nondirectory file)) 706 (unless entry
693 (dir (file-name-directory file))) 707 (setq entry (eshell-parse-ange-ls dir))
694 (if (boundp 'ange-cache) 708 (if (boundp 'ange-cache)
695 (setq entry (cdr (assoc base (cdr (assoc dir ange-cache)))))) 709 (setq ange-cache
696 (unless entry 710 (cons (cons dir entry)
697 (setq entry (eshell-parse-ange-ls dir)) 711 ange-cache)))
698 (if (boundp 'ange-cache) 712 (if entry
699 (setq ange-cache 713 (let ((fentry (assoc base (cdr entry))))
700 (cons (cons dir entry) 714 (if fentry
701 ange-cache))) 715 (setq entry (cdr fentry))
702 (if entry 716 (setq entry nil))))))
703 (let ((fentry (assoc base (cdr entry)))) 717 (file-attributes file))))
704 (if fentry
705 (setq entry (cdr fentry))
706 (setq entry nil)))))))
707 (or entry (funcall handler 'file-attributes file)))))
708 718
709(defalias 'eshell-copy-tree 'copy-tree) 719(defalias 'eshell-copy-tree 'copy-tree)
710 720
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index d6b59341772..795c7eefc38 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2383,6 +2383,35 @@ been set up by `rfn-eshadow-setup-minibuffer'."
2383 'tramp-rfn-eshadow-update-overlay)))) 2383 'tramp-rfn-eshadow-update-overlay))))
2384 2384
2385 2385
2386;;; Integration of eshell.el:
2387
2388(eval-when-compile
2389 (defvar eshell-path-env))
2390
2391;; eshell.el keeps the path in `eshell-path-env'. We must change it
2392;; when `default-directory' points to another host.
2393(defun tramp-eshell-directory-change ()
2394 "Set `eshell-path-env' to $PATH of the host related to `default-directory'."
2395 (setq eshell-path-env
2396 (if (file-remote-p default-directory)
2397 (with-parsed-tramp-file-name default-directory nil
2398 (mapconcat
2399 'identity
2400 (tramp-get-remote-path v)
2401 ":"))
2402 (getenv "PATH"))))
2403
2404(eval-after-load "esh-util"
2405 '(progn
2406 (tramp-eshell-directory-change)
2407 (add-hook 'eshell-directory-change-hook
2408 'tramp-eshell-directory-change)
2409 (add-hook 'tramp-unload-hook
2410 (lambda ()
2411 (remove-hook 'eshell-directory-change-hook
2412 'tramp-eshell-directory-change)))))
2413
2414
2386;;; File Name Handler Functions: 2415;;; File Name Handler Functions:
2387 2416
2388(defun tramp-handle-make-symbolic-link 2417(defun tramp-handle-make-symbolic-link