[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master a49ecdd0ff: Keep subcommands in pipelines from clobbering the hea
From: |
Lars Ingebrigtsen |
Subject: |
master a49ecdd0ff: Keep subcommands in pipelines from clobbering the head/tail processes |
Date: |
Tue, 24 May 2022 08:58:44 -0400 (EDT) |
branch: master
commit a49ecdd0ff2b2526fcc519bb23ce1f5113c8fb1d
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
Keep subcommands in pipelines from clobbering the head/tail processes
* lisp/eshell/esh-cmd.el (eshell-execute-pipeline): Use 'make-symbol'
for headproc and tailproc.
(eshell-do-pipelines, eshell-do-pipelines-synchronously): Adapt to the
above.
* test/lisp/eshell/eshell-tests.el (eshell-test/pipe-subcommand)
(eshell-test/pipe-subcommand-with-pipe): New test.
* doc/misc/eshell.texi (Bugs and ideas): Remove item about piping to
process from loop; this commit fixes it (bug#55590).
---
doc/misc/eshell.texi | 8 --------
lisp/eshell/esh-cmd.el | 15 ++++++++++-----
test/lisp/eshell/eshell-tests.el | 16 ++++++++++++++++
3 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index d35a642b62..85e5a4933f 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -1758,14 +1758,6 @@ alias arg=blah
function arg () @{ blah $* @}
@end example
-@item @samp{for i in 1 2 3 @{ grep -q a b && *echo has it @} | wc -l} outputs
result after prompt
-
-In fact, piping to a process from a looping construct doesn't work in
-general. If I change the call to @code{eshell-copy-handles} in
-@code{eshell-rewrite-for-command} to use @code{eshell-protect}, it seems
-to work, but the output occurs after the prompt is displayed. The whole
-structured command thing is too complicated at present.
-
@item Pcomplete sometimes gets stuck
You press @key{TAB}, but no completions appear, even though the
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 42616e7037..73c250632c 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -827,8 +827,8 @@ This macro calls itself recursively, with NOTFIRST non-nil."
((cdr pipeline) t)
(t (quote 'last)))))
(let ((proc ,(car pipeline)))
- (setq headproc (or proc headproc))
- (setq tailproc (or tailproc proc))
+ (set headproc (or proc (symbol-value headproc)))
+ (set tailproc (or (symbol-value tailproc) proc))
proc))))))
(defmacro eshell-do-pipelines-synchronously (pipeline)
@@ -861,7 +861,7 @@ This is used on systems where async subprocesses are not
supported."
(let ((result ,(car pipeline)))
;; tailproc gets the result of the last successful process in
;; the pipeline.
- (setq tailproc (or result tailproc))
+ (set tailproc (or result (symbol-value tailproc)))
,(if (cdr pipeline)
`(eshell-do-pipelines-synchronously (quote ,(cdr pipeline))))
result))))
@@ -870,7 +870,11 @@ This is used on systems where async subprocesses are not
supported."
(defmacro eshell-execute-pipeline (pipeline)
"Execute the commands in PIPELINE, connecting each to one another."
- `(let ((eshell-in-pipeline-p t) headproc tailproc)
+ `(let ((eshell-in-pipeline-p t)
+ (headproc (make-symbol "headproc"))
+ (tailproc (make-symbol "tailproc")))
+ (set headproc nil)
+ (set tailproc nil)
(progn
,(if (fboundp 'make-process)
`(eshell-do-pipelines ,pipeline)
@@ -880,7 +884,8 @@ This is used on systems where async subprocesses are not
supported."
(car (aref eshell-current-handles
,eshell-error-handle)) nil)))
(eshell-do-pipelines-synchronously ,pipeline)))
- (eshell-process-identity (cons headproc tailproc)))))
+ (eshell-process-identity (cons (symbol-value headproc)
+ (symbol-value tailproc))))))
(defmacro eshell-as-subcommand (command)
"Execute COMMAND using a temp buffer.
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 7cdeb017e4..c0affed80a 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -114,6 +114,22 @@ e.g. \"{(+ 1 2)} 3\" => 3"
(eshell-wait-for-subprocess)
(eshell-match-result "OLLEH\n")))
+(ert-deftest eshell-test/pipe-subcommand ()
+ "Check that piping with an asynchronous subcommand works"
+ (skip-unless (and (executable-find "echo")
+ (executable-find "cat")))
+ (with-temp-eshell
+ (eshell-command-result-p "echo ${*echo hi} | *cat"
+ "hi")))
+
+(ert-deftest eshell-test/pipe-subcommand-with-pipe ()
+ "Check that piping with an asynchronous subcommand with its own pipe works"
+ (skip-unless (and (executable-find "echo")
+ (executable-find "cat")))
+ (with-temp-eshell
+ (eshell-command-result-p "echo ${*echo hi | *cat} | *cat"
+ "hi")))
+
(ert-deftest eshell-test/redirect-buffer ()
"Check that piping to a buffer works"
(with-temp-buffer
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master a49ecdd0ff: Keep subcommands in pipelines from clobbering the head/tail processes,
Lars Ingebrigtsen <=