mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
Allow specifying stdout/stderr separately in some Eshell commands
* lisp/eshell/eshell.el (eshell-command): Add ERROR-TARGET. * lisp/eshell/em-script.el (eshell-execute-file): Make interactive, and add ERROR-TARGET. * doc/misc/eshell.texi (One-Off Commands, Scripts): Update documentation. * etc/NEWS: Announce this change.
This commit is contained in:
parent
965be7bc46
commit
99b360bb5a
@ -235,11 +235,19 @@ Start a new Eshell session, no matter if another one already exists.
|
||||
|
||||
You can also run individual Eshell commands from anywhere within Emacs:
|
||||
|
||||
@deffn Command eshell-command command &optional to-current-buffer
|
||||
@deffn Command eshell-command command &optional output-target error-target
|
||||
Execute the Eshell command string @var{command} and show the output in a
|
||||
buffer. If @var{to-current-buffer} is non-@code{nil} (interactively,
|
||||
with the prefix argument), then insert output into the current buffer at
|
||||
point.
|
||||
buffer. If @var{output-target} is @code{t} (interactively, with the
|
||||
prefix argument), write the command's standard output to the current
|
||||
buffer at point. If @code{nil}, write the output to a new output
|
||||
buffer. For any other value, output to that Eshell target
|
||||
(@pxref{Redirection}).
|
||||
|
||||
@var{error-target} is similar to @var{output-target}, except that it
|
||||
controls where to write standard error, and a @code{nil} value means to
|
||||
write standard error to the same place as standard output. (To suppress
|
||||
standard error, you can write to the Eshell virtual target
|
||||
@file{/dev/null}.)
|
||||
|
||||
When the command ends with @kbd{&}, Eshell will evaluate the command
|
||||
asynchronously. Otherwise, it will wait until the command has finished
|
||||
@ -275,13 +283,20 @@ the special variables @code{$0}, @code{$1}, @dots{}, @code{$9}, and
|
||||
|
||||
You can also invoke Eshell scripts from outside of Eshell:
|
||||
|
||||
@defun eshell-execute-file file &optional args destination
|
||||
@deffn Command eshell-execute-file file &optional args output-target error-target
|
||||
Execute the Eshell commands contained in @var{file}, passing an optional
|
||||
list of @var{args} to the script. If @var{destination} is @code{t},
|
||||
write the command output to the current buffer. If @code{nil}, don't
|
||||
write the output anywhere. For any other value, output to the
|
||||
corresponding Eshell target (@pxref{Redirection}).
|
||||
@end defun
|
||||
list of @var{args} to the script. If @var{output-target} is @code{t}
|
||||
(interactively, with the prefix argument), write the command output to
|
||||
the current buffer. If @code{nil}, don't write the output anywhere.
|
||||
For any other value, output to the corresponding Eshell target
|
||||
(@pxref{Redirection}).
|
||||
|
||||
@var{error-target} is similar to @var{output-target}, except that it
|
||||
controls where to write standard error, and a @code{nil} value means to
|
||||
write standard error to the same place as standard output. (To suppress
|
||||
standard error, you can write to the Eshell virtual target
|
||||
@file{/dev/null\}.)
|
||||
@end deffn
|
||||
|
||||
@cindex batch scripts
|
||||
@defun eshell-batch-file
|
||||
|
12
etc/NEWS
12
etc/NEWS
@ -60,6 +60,18 @@ this will prompt for confirmation before creating a new buffer when
|
||||
necessary. To restore the previous behavior, set this option to
|
||||
'confirm-kill-process'.
|
||||
|
||||
+++
|
||||
*** 'eshell-execute-file' is now an interactive command.
|
||||
Interactively, this now prompts for a script file to execute. With the
|
||||
prefix argument, it will also insert any output into the current buffer
|
||||
at point.
|
||||
|
||||
+++
|
||||
*** 'eshell-command' and 'eshell-execute-file' can now set where stderr goes.
|
||||
These functions now take an optional ERROR-TARGET argument to control
|
||||
where to send the standard error output. See the "(eshell) Entry
|
||||
Points" node in the Eshell manual for more details.
|
||||
|
||||
+++
|
||||
*** Eshell's built-in "wait" command now accepts a timeout.
|
||||
By passing "-t" or "--timeout", you can specify a maximum time to wait
|
||||
|
@ -106,20 +106,29 @@ Comments begin with `#'."
|
||||
(eshell--source-file file args subcommand-p)))
|
||||
|
||||
;;;###autoload
|
||||
(defun eshell-execute-file (file &optional args destination)
|
||||
(defun eshell-execute-file (file &optional args output-target error-target)
|
||||
"Execute a series of Eshell commands in FILE, passing ARGS.
|
||||
If DESTINATION is t, write the command output to the current buffer. If
|
||||
nil, don't write the output anywhere. For any other value, output to
|
||||
the corresponding Eshell target (see `eshell-get-target').
|
||||
If OUTPUT-TARGET is t (interactively, with the prefix argument), write
|
||||
the command's standard output to the current buffer at point. If nil,
|
||||
don't write the output anywhere. For any other value, output to that
|
||||
Eshell target (see `eshell-get-target').
|
||||
|
||||
ERROR-TARGET is similar to OUTPUT-TARGET, except that it controls where
|
||||
to write standard error, and a nil value means to write standard error
|
||||
to the same place as standard output. (To suppress standard error, you
|
||||
can write to the Eshell virtual target \"/dev/null\".)
|
||||
|
||||
Comments begin with `#'."
|
||||
(interactive (list (read-file-name "Execute file: " nil nil t)
|
||||
nil (not (not current-prefix-arg))))
|
||||
(let ((eshell-non-interactive-p t)
|
||||
(stdout (if (eq destination t) (current-buffer) destination)))
|
||||
(stdout (if (eq output-target t) (current-buffer) output-target))
|
||||
(stderr (if (eq error-target t) (current-buffer) error-target)))
|
||||
(with-temp-buffer
|
||||
(eshell-mode)
|
||||
(eshell-do-eval
|
||||
`(let ((eshell-current-handles
|
||||
(eshell-create-handles ,stdout 'insert))
|
||||
(eshell-create-handles ,stdout 'insert ,stderr 'insert))
|
||||
(eshell-current-subjob-p))
|
||||
,(eshell--source-file file args))
|
||||
t))))
|
||||
|
@ -327,31 +327,42 @@ information on Eshell, see Info node `(eshell)Top'."
|
||||
(defvar eshell-command-buffer-name-sync "*Eshell Command Output*")
|
||||
|
||||
;;;###autoload
|
||||
(defun eshell-command (command &optional to-current-buffer)
|
||||
(defun eshell-command (command &optional output-target error-target)
|
||||
"Execute the Eshell command string COMMAND.
|
||||
If TO-CURRENT-BUFFER is non-nil (interactively, with the prefix
|
||||
argument), then insert output into the current buffer at point.
|
||||
If OUTPUT-TARGET is t (interactively, with the prefix argument), write
|
||||
the command's standard output to the current buffer at point. If nil,
|
||||
write the output to a new output buffer. For any other value, output to
|
||||
that Eshell target (see `eshell-get-target').
|
||||
|
||||
When \"&\" is added at end of command, the command is async and its output
|
||||
appears in a specific buffer. You can customize
|
||||
ERROR-TARGET is similar to OUTPUT-TARGET, except that it controls where
|
||||
to write standard error, and a nil value means to write standard error
|
||||
to the same place as standard output. (To suppress standard error, you
|
||||
can write to the Eshell virtual target \"/dev/null\".)
|
||||
|
||||
When \"&\" is added at end of command, the command is async and its
|
||||
output appears in a specific buffer. You can customize
|
||||
`eshell-command-async-buffer' to specify what to do when this output
|
||||
buffer is already taken by another running shell command."
|
||||
(interactive (list (eshell-read-command)
|
||||
current-prefix-arg))
|
||||
(not (not current-prefix-arg))))
|
||||
(save-excursion
|
||||
(let ((stdout (if to-current-buffer (current-buffer) t))
|
||||
(let ((stdout (cond ((eq output-target t) (current-buffer))
|
||||
((not output-target) t)
|
||||
(t output-target)))
|
||||
(stderr (if (eq error-target t) (current-buffer) error-target))
|
||||
(buf (set-buffer (generate-new-buffer " *eshell cmd*")))
|
||||
(eshell-non-interactive-p t))
|
||||
(eshell-mode)
|
||||
(let* ((proc (eshell-eval-command
|
||||
`(let ((eshell-current-handles
|
||||
(eshell-create-handles ,stdout 'insert))
|
||||
(eshell-create-handles ,stdout 'insert
|
||||
,stderr 'insert))
|
||||
(eshell-current-subjob-p))
|
||||
,(eshell-parse-command command))
|
||||
command))
|
||||
(async (eq (car-safe proc) :eshell-background))
|
||||
(bufname (cond
|
||||
(to-current-buffer nil)
|
||||
((not (eq stdout t)) nil)
|
||||
(async eshell-command-buffer-name-async)
|
||||
(t eshell-command-buffer-name-sync)))
|
||||
unique)
|
||||
@ -394,7 +405,7 @@ buffer is already taken by another running shell command."
|
||||
(while (and (bolp) (not (bobp)))
|
||||
(delete-char -1)))
|
||||
(cl-assert (and buf (buffer-live-p buf)))
|
||||
(unless to-current-buffer
|
||||
(unless bufname
|
||||
(let ((len (if async 2
|
||||
(count-lines (point-min) (point-max)))))
|
||||
(cond
|
||||
|
Loading…
Reference in New Issue
Block a user