summaryrefslogtreecommitdiff
path: root/lisp/eshell/esh-util.el
diff options
context:
space:
mode:
authorJim Porter <jporterbugs@gmail.com>2022-01-30 18:53:53 -0800
committerLars Ingebrigtsen <larsi@gnus.org>2022-02-03 20:02:22 +0100
commit3a388ab4a604f868ab2c1f9b3c63a7f7a3221f7f (patch)
treee0c4cb817c5dc16179305307ec0b56e527d7f36d /lisp/eshell/esh-util.el
parent2e60ef696a3cf16b0eb297948e27ba0cb32a125e (diff)
downloademacs-3a388ab4a604f868ab2c1f9b3c63a7f7a3221f7f.tar.gz
When executing an Eshell pipeline, send input to the first process
Previously, input was sent to the last process in the pipeline, resulting in unexpected behavior when running commands like 'tr a-z A-Z | rev'. * lisp/eshell/esh-util.el (eshell-process-pair-p) (eshell-make-process-pair): New functions. * lisp/eshell/esh-cmd.el (eshell-last-async-proc): Rename to... (eshell-last-async-procs): ... this, and store a pair of processes. (eshell-interactive-process): Replace with... (eshell-interactive-process-p, eshell-head-process) (eshell-tail-process): ... these. (eshell-cmd-initialize): Set 'eshell-last-async-procs'. (eshell-do-pipelines): Set 'headproc'. (eshell-execute-pipeline): Return 'headproc' and 'tailproc'. (eshell-resume-eval): Use 'eshell-last-async-procs'. (eshell-do-eval): Make sure we work with a pair of processes. * lisp/eshell/esh-proc.el (eshell-send-eof-to-process): Move from here... * lisp/eshell/esh-mode.el (eshell-send-eof-to-process): ... to here, and only send EOF to the head process. * lisp/eshell/em-cmpl.el (eshell-complete-parse-arguments) * lisp/eshell/esh-mode.el (eshell-intercept-commands) (eshell-watch-for-password-prompt): Use 'eshell-interactive-process-p'. * lisp/eshell/em-rebind.el (eshell-delchar-or-maybe-eof) * lisp/eshell/em-term.el (eshell-term-send-raw-string) * lisp/eshell/esh-mode.el (eshell-self-insert-command) (eshell-send-input, eshell-send-invisible): Use 'eshell-head-process'. * lisp/eshell/esh-cmd.el (eshell-as-subcommand): Use 'eshell-tail-process'. * lisp/eshell/eshell.el (eshell-command): * test/lisp/eshell/eshell-tests-helpers.el (eshell-wait-for-subprocess): Use 'eshell-interactive-process-p' and 'eshell-tail-process'. * test/lisp/eshell/eshell-tests.el (eshell-test/pipe-headproc-stdin): New test.
Diffstat (limited to 'lisp/eshell/esh-util.el')
-rw-r--r--lisp/eshell/esh-util.el14
1 files changed, 14 insertions, 0 deletions
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 0e04dbc7c9f..788404fc43a 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -609,6 +609,20 @@ gid format. Valid values are `string' and `integer', defaulting to
"If the `processp' function does not exist, PROC is not a process."
(and (fboundp 'processp) (processp proc)))
+(defun eshell-process-pair-p (procs)
+ "Return non-nil if PROCS is a pair of process objects."
+ (and (consp procs)
+ (eshell-processp (car procs))
+ (eshell-processp (cdr procs))))
+
+(defun eshell-make-process-pair (procs)
+ "Make a pair of process objects from PROCS if possible.
+This represents the head and tail of a pipeline of processes,
+where the head and tail may be the same process."
+ (pcase procs
+ ((pred eshell-processp) (cons procs procs))
+ ((pred eshell-process-pair-p) procs)))
+
;; (defun eshell-copy-file
;; (file newname &optional ok-if-already-exists keep-date)
;; "Copy FILE to NEWNAME. See docs for `copy-file'."