emacs-diffs
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]