diff options
| author | Michael Albinus | 2009-11-24 10:25:54 +0000 |
|---|---|---|
| committer | Michael Albinus | 2009-11-24 10:25:54 +0000 |
| commit | 605a20a98823768578d6faed5f04cb00e57da2bb (patch) | |
| tree | 525322a2fc9fbabb9d8bebc014e51d061aeff7c2 | |
| parent | 937e60c88bfbbc44d44806a7cf43d5f982a8026f (diff) | |
| download | emacs-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/ChangeLog | 26 | ||||
| -rw-r--r-- | lisp/eshell/em-cmpl.el | 2 | ||||
| -rw-r--r-- | lisp/eshell/em-unix.el | 5 | ||||
| -rw-r--r-- | lisp/eshell/esh-ext.el | 37 | ||||
| -rw-r--r-- | lisp/eshell/esh-proc.el | 9 | ||||
| -rw-r--r-- | lisp/eshell/esh-util.el | 52 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 29 |
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 @@ | |||
| 1 | 2009-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 | |||
| 1 | 2009-11-24 Tassilo Horn <tassilo@member.fsf.org> | 27 | 2009-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. |
| 181 | A remote command is something that executes on a different machine. | 181 | A remote command is something that executes on a different machine. |
| 182 | An external command simply means external to Emacs. | 182 | An 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. | ||
| 242 | It 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'. | ||
| 247 | Prepend 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 |