[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 99b360bb5aa: Allow specifying stdout/stderr separately in some Es
From: |
Jim Porter |
Subject: |
master 99b360bb5aa: Allow specifying stdout/stderr separately in some Eshell commands |
Date: |
Thu, 18 Jul 2024 19:13:57 -0400 (EDT) |
branch: master
commit 99b360bb5aabf324cf038c27ac76ac1513319754
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Jim Porter <jporterbugs@gmail.com>
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.
---
doc/misc/eshell.texi | 35 +++++++++++++++++++++++++----------
etc/NEWS | 12 ++++++++++++
lisp/eshell/em-script.el | 21 +++++++++++++++------
lisp/eshell/eshell.el | 33 ++++++++++++++++++++++-----------
4 files changed, 74 insertions(+), 27 deletions(-)
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index d4e182bcbb2..8a4f460d03c 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -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
diff --git a/etc/NEWS b/etc/NEWS
index 60bde2abb40..5429db1dded 100644
--- a/etc/NEWS
+++ b/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
diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el
index ba020d2eb5b..80dea16106b 100644
--- a/lisp/eshell/em-script.el
+++ b/lisp/eshell/em-script.el
@@ -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))))
diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el
index d60101d51e1..6637ff36a2c 100644
--- a/lisp/eshell/eshell.el
+++ b/lisp/eshell/eshell.el
@@ -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.
-
-When \"&\" is added at end of command, the command is async and its output
-appears in a specific buffer. You can customize
+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').
+
+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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 99b360bb5aa: Allow specifying stdout/stderr separately in some Eshell commands,
Jim Porter <=