# HG changeset patch # User Michael Albinus # Date 1259058354 0 # Node ID 16b061d2742d87690008b99f1ca6d70072b2c9a4 # Parent 8ccde493b34de404d4800873dc2fd987fa4c5580 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'. diff -r 8ccde493b34d -r 16b061d2742d lisp/ChangeLog --- a/lisp/ChangeLog Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/ChangeLog Tue Nov 24 10:25:54 2009 +0000 @@ -1,3 +1,29 @@ +2009-11-24 Michael Albinus + + 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'. + 2009-11-24 Tassilo Horn * doc-view.el (doc-view-mode): Switch off view-mode explicitly, diff -r 8ccde493b34d -r 16b061d2742d lisp/eshell/em-cmpl.el --- a/lisp/eshell/em-cmpl.el Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/eshell/em-cmpl.el Tue Nov 24 10:25:54 2009 +0000 @@ -402,7 +402,7 @@ (setq filename (substring filename 1) pcomplete-stub filename glob-name t)) - (let* ((paths (split-string (getenv "PATH") path-separator)) + (let* ((paths (eshell-parse-colon-path eshell-path-env)) (cwd (file-name-as-directory (expand-file-name default-directory))) (path "") (comps-in-path ()) diff -r 8ccde493b34d -r 16b061d2742d lisp/eshell/em-unix.el --- a/lisp/eshell/em-unix.el Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/eshell/em-unix.el Tue Nov 24 10:25:54 2009 +0000 @@ -859,9 +859,8 @@ (if (and ext-du (not (catch 'have-ange-path (eshell-for arg args - (if (eq (find-file-name-handler (expand-file-name arg) - 'directory-files) - 'ange-ftp-hook-function) + (if (string-equal + (file-remote-p (expand-file-name arg) 'method) "ftp") (throw 'have-ange-path t)))))) (throw 'eshell-replace-command (eshell-parse-command ext-du args)) diff -r 8ccde493b34d -r 16b061d2742d lisp/eshell/esh-ext.el --- a/lisp/eshell/esh-ext.el Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/eshell/esh-ext.el Tue Nov 24 10:25:54 2009 +0000 @@ -73,7 +73,7 @@ "Search the environment path for NAME." (if (file-name-absolute-p name) name - (let ((list (parse-colon-path (getenv "PATH"))) + (let ((list (eshell-parse-colon-path eshell-path-env)) suffixes n1 n2 file) (while list (setq n1 (concat (car list) name)) @@ -176,7 +176,7 @@ (error "%s: external command not found" (substring command 1)))))) -(defun eshell-remote-command (handler command args) +(defun eshell-remote-command (command args) "Insert output from a remote COMMAND, using ARGS. A remote command is something that executes on a different machine. An external command simply means external to Emacs. @@ -190,10 +190,10 @@ (unwind-protect (progn (setq exitcode - (funcall handler 'shell-command - (mapconcat 'shell-quote-argument - (append (list command) args) " ") - outbuf errbuf)) + (shell-command + (mapconcat 'shell-quote-argument + (append (list command) args) " ") + outbuf errbuf)) (eshell-print (with-current-buffer outbuf (buffer-string))) (eshell-error (with-current-buffer errbuf (buffer-string)))) (eshell-close-handles exitcode 'nil) @@ -203,23 +203,14 @@ (defun eshell-external-command (command args) "Insert output from an external COMMAND, using ARGS." (setq args (eshell-stringify-list (eshell-flatten-list args))) - (let ((handler - (unless (or (equal default-directory "/") - (and (eshell-under-windows-p) - (string-match "\\`[A-Za-z]:[/\\\\]\\'" - default-directory))) - (find-file-name-handler default-directory - 'shell-command)))) - (if (and handler - (not (and (featurep 'xemacs) - (eq handler 'dired-handler-fn)))) - (eshell-remote-command handler command args)) - (let ((interp (eshell-find-interpreter command))) - (assert interp) - (if (functionp (car interp)) - (apply (car interp) (append (cdr interp) args)) - (eshell-gather-process-output - (car interp) (append (cdr interp) args)))))) + (if (string-equal (file-remote-p default-directory 'method) "ftp") + (eshell-remote-command command args)) + (let ((interp (eshell-find-interpreter command))) + (assert interp) + (if (functionp (car interp)) + (apply (car interp) (append (cdr interp) args)) + (eshell-gather-process-output + (car interp) (append (cdr interp) args))))) (defun eshell/addpath (&rest args) "Add a set of paths to PATH." diff -r 8ccde493b34d -r 16b061d2742d lisp/eshell/esh-proc.el --- a/lisp/eshell/esh-proc.el Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/eshell/esh-proc.el Tue Nov 24 10:25:54 2009 +0000 @@ -261,7 +261,7 @@ (defun eshell-gather-process-output (command args) "Gather the output from COMMAND + ARGS." (unless (and (file-executable-p command) - (file-regular-p command)) + (file-regular-p (file-truename command))) (error "%s: not an executable file" command)) (let* ((delete-exited-processes (if eshell-current-subjob-p @@ -270,12 +270,13 @@ (process-environment (eshell-environment-variables)) proc decoding encoding changed) (cond - ((fboundp 'start-process) + ((fboundp 'start-file-process) (setq proc (let ((process-connection-type (unless (eshell-needs-pipe-p command) - process-connection-type))) - (apply 'start-process + process-connection-type)) + (command (or (file-remote-p command 'localname) command))) + (apply 'start-file-process (file-name-nondirectory command) nil ;; `start-process' can't deal with relative filenames. (append (list (expand-file-name command)) args)))) diff -r 8ccde493b34d -r 16b061d2742d lisp/eshell/esh-util.el --- a/lisp/eshell/esh-util.el Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/eshell/esh-util.el Tue Nov 24 10:25:54 2009 +0000 @@ -237,6 +237,21 @@ a (last a))) a)) +(defvar eshell-path-env (getenv "PATH") + "Content of $PATH. +It might be different from \(getenv \"PATH\"\), when +`default-directory' points to a remote host.") + +(defun eshell-parse-colon-path (path-env) + "Split string with `parse-colon-path'. +Prepend remote identification of `default-directory', if any." + (let ((remote (file-remote-p default-directory))) + (if remote + (mapcar + (lambda (x) (concat remote x)) + (parse-colon-path path-env)) + (parse-colon-path path-env)))) + (defun eshell-split-path (path) "Split a path into multiple subparts." (let ((len (length path)) @@ -682,29 +697,24 @@ (defun eshell-file-attributes (file) "Return the attributes of FILE, playing tricks if it's over ange-ftp." (let* ((file (expand-file-name file)) - (handler (find-file-name-handler file 'file-attributes)) entry) - (if (not handler) - (file-attributes file) - (if (eq (find-file-name-handler (file-name-directory file) - 'directory-files) - 'ange-ftp-hook-function) - (let ((base (file-name-nondirectory file)) - (dir (file-name-directory file))) + (if (string-equal (file-remote-p file 'method) "ftp") + (let ((base (file-name-nondirectory file)) + (dir (file-name-directory file))) + (if (boundp 'ange-cache) + (setq entry (cdr (assoc base (cdr (assoc dir ange-cache)))))) + (unless entry + (setq entry (eshell-parse-ange-ls dir)) (if (boundp 'ange-cache) - (setq entry (cdr (assoc base (cdr (assoc dir ange-cache)))))) - (unless entry - (setq entry (eshell-parse-ange-ls dir)) - (if (boundp 'ange-cache) - (setq ange-cache - (cons (cons dir entry) - ange-cache))) - (if entry - (let ((fentry (assoc base (cdr entry)))) - (if fentry - (setq entry (cdr fentry)) - (setq entry nil))))))) - (or entry (funcall handler 'file-attributes file))))) + (setq ange-cache + (cons (cons dir entry) + ange-cache))) + (if entry + (let ((fentry (assoc base (cdr entry)))) + (if fentry + (setq entry (cdr fentry)) + (setq entry nil)))))) + (file-attributes file)))) (defalias 'eshell-copy-tree 'copy-tree) diff -r 8ccde493b34d -r 16b061d2742d lisp/net/tramp.el --- a/lisp/net/tramp.el Tue Nov 24 09:19:09 2009 +0000 +++ b/lisp/net/tramp.el Tue Nov 24 10:25:54 2009 +0000 @@ -2383,6 +2383,35 @@ 'tramp-rfn-eshadow-update-overlay)))) +;;; Integration of eshell.el: + +(eval-when-compile + (defvar eshell-path-env)) + +;; eshell.el keeps the path in `eshell-path-env'. We must change it +;; when `default-directory' points to another host. +(defun tramp-eshell-directory-change () + "Set `eshell-path-env' to $PATH of the host related to `default-directory'." + (setq eshell-path-env + (if (file-remote-p default-directory) + (with-parsed-tramp-file-name default-directory nil + (mapconcat + 'identity + (tramp-get-remote-path v) + ":")) + (getenv "PATH")))) + +(eval-after-load "esh-util" + '(progn + (tramp-eshell-directory-change) + (add-hook 'eshell-directory-change-hook + 'tramp-eshell-directory-change) + (add-hook 'tramp-unload-hook + (lambda () + (remove-hook 'eshell-directory-change-hook + 'tramp-eshell-directory-change))))) + + ;;; File Name Handler Functions: (defun tramp-handle-make-symbolic-link