From 70b62fc6173ec25d6c4c82e86af7cb4bacc75baa Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Thu, 30 Mar 2023 17:39:24 -0700 Subject: [PATCH] Fix using background commands in 'eshell-command' Do not merge to master. This regressed due to the patch for bug#53715, which changed how Eshell pipelines return the processes in the pipeline. * lisp/eshell/esh-cmd.el (eshell-eval-command): Allow process-pairs. * test/lisp/eshell/eshell-tests.el (eshell-test/eshell-command/simple) (eshell-test/eshell-command/pipeline) (eshell-test/eshell-command/background) (eshell-test/eshell-command/background-pipeline): New tests. --- lisp/eshell/esh-cmd.el | 8 ++++-- test/lisp/eshell/eshell-tests.el | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index f4ac384ccc5..706477a5f45 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1032,18 +1032,20 @@ eshell-eval-command (setq eshell-current-command command) (let* ((delim (catch 'eshell-incomplete (eshell-resume-eval))) - (val (car-safe delim))) + (val (car-safe delim)) + (val-is-process (or (eshell-processp val) + (eshell-process-pair-p val)))) ;; If the return value of `eshell-resume-eval' is wrapped in a ;; list, it indicates that the command was run asynchronously. ;; In that case, unwrap the value before checking the delimiter ;; value. (if (and val - (not (eshell-processp val)) + (not val-is-process) (not (eq val t))) (error "Unmatched delimiter: %S" val) ;; Eshell-command expect a list like () to know if the ;; command should be async or not. - (or (and (eshell-processp val) delim) val))))) + (or (and val-is-process delim) val))))) (defun eshell-resume-command (proc status) "Resume the current command when a process ends." diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el index 3c4a8ec97ea..b57abe3226c 100644 --- a/test/lisp/eshell/eshell-tests.el +++ b/test/lisp/eshell/eshell-tests.el @@ -105,6 +105,53 @@ eshell-test/lisp-reset-in-pipeline (format template "format \"%s\" eshell-in-pipeline-p") "nil"))) +(ert-deftest eshell-test/eshell-command/simple () + "Test that the `eshell-command' function writes to the current buffer." + (skip-unless (executable-find "echo")) + (ert-with-temp-directory eshell-directory-name + (let ((eshell-history-file-name nil)) + (with-temp-buffer + (eshell-command "*echo hi" t) + (should (equal (buffer-string) "hi\n")))))) + +(ert-deftest eshell-test/eshell-command/pipeline () + "Test that the `eshell-command' function writes to the current buffer. +This test uses a pipeline for the command." + (skip-unless (and (executable-find "echo") + (executable-find "cat"))) + (ert-with-temp-directory eshell-directory-name + (let ((eshell-history-file-name nil)) + (with-temp-buffer + (eshell-command "*echo hi | *cat" t) + (should (equal (buffer-string) "hi\n")))))) + +(ert-deftest eshell-test/eshell-command/background () + "Test that `eshell-command' works for background commands." + (skip-unless (executable-find "echo")) + (ert-with-temp-directory eshell-directory-name + (let ((eshell-history-file-name nil)) + ;; XXX: We can't write to the current buffer here, since + ;; `eshell-command' will produce an invalid command in that + ;; case. Just make sure the command runs and produces an output + ;; buffer. + (eshell-command "*echo hi &") + (with-current-buffer "*Eshell Async Command Output*" + (goto-char (point-min)) + (should (looking-at "\\[echo\\(<[0-9]+>\\)?\\]")))))) + +(ert-deftest eshell-test/eshell-command/background-pipeline () + "Test that `eshell-command' works for background commands. +This test uses a pipeline for the command." + (skip-unless (and (executable-find "echo") + (executable-find "cat"))) + (ert-with-temp-directory eshell-directory-name + (let ((eshell-history-file-name nil)) + ;; XXX: As above, we can't write to the current buffer here. + (eshell-command "*echo hi | *cat &") + (with-current-buffer "*Eshell Async Command Output*" + (goto-char (point-min)) + (should (looking-at "\\[cat\\(<[0-9]+>\\)?\\]")))))) + (ert-deftest eshell-test/command-running-p () "Modeline should show no command running" (with-temp-eshell -- 2.25.1