master d5fea6863cc 8/8: Document Eshell's Lisp pipes feature
Jim Porter <[email protected]>
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: master commit d5fea6863cc5d95b7af9052c1e7d5347693a6e41 Author: Jim Porter <[email protected]> Commit: Jim Porter <[email protected]> Document Eshell's Lisp pipes feature * doc/misc/eshell.texi (List of Built-ins): Document 'accumulate', 'apply-lines', and 'map-lines'. (Pipelines): Add menu. (Lisp Pipelines): New section. (Bugs and ideas): Remove implemented idea. * etc/NEWS: Announce this change. --- doc/misc/eshell.texi | 93 ++++++++++++++++++++++++++++++++++++++++++++++++---- etc/NEWS | 13 ++++++++ 2 files changed, 99 insertions(+), 7 deletions(-) diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index ac76d25aa44..92f1d296469 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi @@ -650,6 +650,12 @@ passing any @var{arguments} to the script (@pxref{Scripts}). This is not to be confused with the command @command{source}, which sources a file in a subshell environment. +@cmindex accumulate +@item accumulate @var{function} +When used as a pipe target (@pxref{Lisp Pipelines}), this accumulates +all the output from the left side of the pipe and passes it to +@var{function} as a single argument. + @cmindex addpath @item addpath @itemx addpath [-b] @var{directory}@dots{} @@ -670,6 +676,12 @@ adding it to the aliases file (@pxref{Aliases}). If @var{command} is omitted, delete the alias named @var{name}. With no arguments at all, list all the currently-defined aliases. +@cmindex apply-lines +@item apply-lines @var{function} +When used as a pipe target (@pxref{Lisp Pipelines}), this passes each +line of output from the left side of the pipe as a list of arguments to +@var{function}. + @cmindex basename @item basename @var{filename} Return @var{filename} without its directory. @@ -1175,6 +1187,12 @@ Manual}. Otherwise call the external @command{make} command. Display Man pages using the Emacs @code{man} command. @xref{Man Page, , , emacs, The GNU Emacs Manual}. +@cmindex map-lines +@item map-lines @var{function} +When used as a pipe target (@pxref{Lisp Pipelines}), this calls +@var{function} once for each line of output from the left side of the +pipe with that line as a single argument. + @cmindex mkdir @item mkdir [-p] @var{directory}@dots{} Make new directories. With @code{-p} or @code{--parents}, @@ -2503,6 +2521,71 @@ olleh To send both the standard output and standard error of a command to another command's input, you can use the @code{|&} operator. +@menu +* Lisp Pipelines:: +* Running Shell Pipelines Natively:: +@end menu + +@node Lisp Pipelines +@subsection Lisp Pipelines + +In addition to piping data to ordinary programs on your system, Eshell +supports piping to ordinary Lisp functions. This lets you mix and match +external commands and Lisp functions in your pipelines to manipulate +output however works best. Normally in Eshell, entering the bare name +of a function in a command calls that function, so e.g.@: @samp{ding} +will beep or flash the screen. To avoid this, pass the quoted name of +the function: + +@example +~ $ echo hello | #'upcase +HELLO +@end example + +You can also use forms that return a function, such as @code{lambda}: + +@example +~ $ echo hello | (lambda (i) (format ">> %s" i)) +>> hello +@end example + +For simple cases, the above is likely all you need. When passed +directly as a pipe target like this, Eshell collects all the output from +the left side of the pipe and passes it as a single argument to the +right side. However, Lisp functions have many other ways they could be +called, so Eshell supports these with some higher-order commands: + +@table @code + +@cmindex accumulate +@item accumulate @var{function} +This is equivalent to passing @var{function} directly as a pipe target, +accumulating all the output from the left side of the pipe and passing +it as a single argument to @var{function}. + +@cmindex map-lines +@item map-lines @var{function} +For each line of output from the left side of the pipe, call +@var{function} with that line as a single argument. For example, you +could "quote" some output for pasting into an email like this: + +@example +cat some-file.txt | map-lines (lambda (i) (format "> %s" i)) +@end example + +@cmindex apply-lines +@item apply-lines @var{function} +Pass each line of output from the left side of the pipe as a list of +arguments to @var{function}. For example, to sum up a list of numbers +written one per line: + +@example +cat numbers.txt | apply-lines #'+ +@end example + +@end table + +@node Running Shell Pipelines Natively @subsection Running Shell Pipelines Natively When constructing shell pipelines that will move a lot of data, it is a good idea to bypass Eshell's own pipelining support and use the @@ -3016,15 +3099,11 @@ scrolls back. @item Use a timer instead of @code{sleep-for} when killing child processes -@item Piping to a Lisp function is not supported - -Make it so that the Lisp command on the right of the pipe is repeatedly -called with the input strings as arguments. This will require changing -@code{eshell-do-pipelines} to handle non-process targets. - @item Input redirection is not supported -See the above entry. +With support for piping to Lisp functions, this should mostly be a +matter of parsing the redirection operator and generating a Lisp form +roughly equivalent to what @code{cat file.txt | some-command} produces. @item Problem running @command{less} without arguments on Windows diff --git a/etc/NEWS b/etc/NEWS index 9a88a6d4403..c6da6290ac3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -273,6 +273,19 @@ commands, such as 'C-x C-f'. If this option is set to non-nil, displayed times (clocked in/out since, time to leave) will use 24-hour clock instead of 12-hour clock. +** Eshell + ++++ +*** Eshell now supports piping output to Lisp functions. +You can now manipulate the output of other commands using the many Lisp +functions provided in Emacs. For example, to uppercase the output of +some other command: + + echo hi | #'upcase + +See the "(eshell) Lisp Pipelines" node in the Eshell manual for more +details. + * New Modes and Packages in Emacs 32.1