Fix using background commands in 'eshell-command'
This regressed due to the patch for bug#53715, which changed how Eshell pipelines return the processes in the pipeline (bug#62556). * lisp/eshell/esh-cmd.el (eshell-parse-command): When creating background commands, wrap the process(es) in a cons cell whose CAR is ':eshell-background'. This lets us use fewer heuristics... (eshell-eval-command): ... here. Additionally, keep the result and the incomplete delimiter separate. * lisp/eshell/eshell.el (eshell-command): Check ':eshell-background' and use a more-robust method for setting the output target. * 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.
This commit is contained in:
parent
6df2941c1b
commit
267fca267f
3 changed files with 65 additions and 30 deletions
|
|
@ -421,7 +421,8 @@ hooks should be run before and after the command."
|
|||
(string= (car eshell--sep-terms) ";"))
|
||||
(eshell-parse-pipeline cmd)
|
||||
`(eshell-do-subjob
|
||||
(list ,(eshell-parse-pipeline cmd)))))
|
||||
(cons :eshell-background
|
||||
,(eshell-parse-pipeline cmd)))))
|
||||
(setq eshell--sep-terms (cdr eshell--sep-terms))
|
||||
(if eshell-in-pipeline-p
|
||||
cmd
|
||||
|
|
@ -1036,7 +1037,12 @@ produced by `eshell-parse-command'."
|
|||
(cadr result)))
|
||||
|
||||
(defun eshell-eval-command (command &optional input)
|
||||
"Evaluate the given COMMAND iteratively."
|
||||
"Evaluate the given COMMAND iteratively.
|
||||
Return the process (or head and tail processes) created by
|
||||
COMMAND, if any. If COMMAND is a background command, return the
|
||||
process(es) in a cons cell like:
|
||||
|
||||
(:eshell-background . PROCESS)"
|
||||
(if eshell-current-command
|
||||
;; We can just stick the new command at the end of the current
|
||||
;; one, and everything will happen as it should.
|
||||
|
|
@ -1052,20 +1058,12 @@ produced by `eshell-parse-command'."
|
|||
(erase-buffer)
|
||||
(insert "command: \"" input "\"\n")))
|
||||
(setq eshell-current-command command)
|
||||
(let* ((delim (catch 'eshell-incomplete
|
||||
(eshell-resume-eval)))
|
||||
(val (car-safe delim)))
|
||||
;; 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 (eq val t)))
|
||||
(error "Unmatched delimiter: %S" val)
|
||||
;; Eshell-command expect a list like (<process>) to know if the
|
||||
;; command should be async or not.
|
||||
(or (and (eshell-processp val) delim) val)))))
|
||||
(let* (result
|
||||
(delim (catch 'eshell-incomplete
|
||||
(ignore (setq result (eshell-resume-eval))))))
|
||||
(when delim
|
||||
(error "Unmatched delimiter: %S" delim))
|
||||
result)))
|
||||
|
||||
(defun eshell-resume-command (proc status)
|
||||
"Resume the current command when a process ends."
|
||||
|
|
|
|||
|
|
@ -290,25 +290,18 @@ With prefix ARG, insert output into the current buffer at point."
|
|||
(eshell-add-input-to-history command)))))
|
||||
(unless command
|
||||
(error "No command specified!"))
|
||||
;; redirection into the current buffer is achieved by adding an
|
||||
;; output redirection to the end of the command, of the form
|
||||
;; 'COMMAND >>> #<buffer BUFFER>'. This will not interfere with
|
||||
;; other redirections, since multiple redirections merely cause the
|
||||
;; output to be copied to multiple target locations
|
||||
(if arg
|
||||
(setq command
|
||||
(concat command
|
||||
(format " >>> #<buffer %s>"
|
||||
(buffer-name (current-buffer))))))
|
||||
(save-excursion
|
||||
(let ((buf (set-buffer (generate-new-buffer " *eshell cmd*")))
|
||||
(let ((stdout (if arg (current-buffer) t))
|
||||
(buf (set-buffer (generate-new-buffer " *eshell cmd*")))
|
||||
(eshell-non-interactive-p t))
|
||||
(eshell-mode)
|
||||
(let* ((proc (eshell-eval-command
|
||||
(list 'eshell-commands
|
||||
(eshell-parse-command command))))
|
||||
`(let ((eshell-current-handles
|
||||
(eshell-create-handles ,stdout 'insert))
|
||||
(eshell-current-subjob-p))
|
||||
,(eshell-parse-command command))))
|
||||
intr
|
||||
(bufname (if (and proc (listp proc))
|
||||
(bufname (if (eq (car-safe proc) :eshell-background)
|
||||
"*Eshell Async Command Output*"
|
||||
(setq intr t)
|
||||
"*Eshell Command Output*")))
|
||||
|
|
|
|||
|
|
@ -107,6 +107,50 @@
|
|||
(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 ((orig-processes (process-list))
|
||||
(eshell-history-file-name nil))
|
||||
(with-temp-buffer
|
||||
(eshell-command "*echo hi &" t)
|
||||
(eshell-wait-for (lambda () (equal (process-list) orig-processes)))
|
||||
(should (equal (buffer-string) "hi\n"))))))
|
||||
|
||||
(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 ((orig-processes (copy-tree (process-list)))
|
||||
(eshell-history-file-name nil))
|
||||
(with-temp-buffer
|
||||
(eshell-command "*echo hi | *cat &" t)
|
||||
(eshell-wait-for (lambda () (equal (process-list) orig-processes)))
|
||||
(should (equal (buffer-string) "hi\n"))))))
|
||||
|
||||
(ert-deftest eshell-test/command-running-p ()
|
||||
"Modeline should show no command running"
|
||||
(with-temp-eshell
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue