1

I know eshell supports output redirection to buffers

cmd > #<buffername>

Is there a way to do piping buffer contents into command? I would like to have something like

cat #<buffername> | cmd 

The problem is that cat is not a builtin so it doesn't know emacs buffers. I could always save the buffer buffername to a file and then cat it but that is not always desired (e.g r-o filesystem)

In more detail

I am passing from using a terminal emulator with zsh towards using eshell. Often I write scripts that run a command, pipe the output into grep,gawk, sed or whatnot and then pipe the result into another program.

I would like to separate this into steps. I know eshell supports output redirection to buffer via

cmb > #<buffername>

I would then process the contents of buffername using powerful emacs tools. I know then that eshell does not support input redirection. I read in some manual to use pipes instead.

If I saved the output to a file with cmb > filename I could then do

cat filename | cmd2

but sometimes saving a buffername to a file filename is impossible or inconvenient. Any tips?

GenaU
  • 103
  • 8

1 Answers1

2

You can use M-| (shell-command-on-region).

Within eshell, you can use

~ $ (with-current-buffer "*scratch*" (buffer-string)) | nl
     1  ;; This buffer is for text that is not saved, and for Lisp evaluation.
     2  ;; To create a file, visit it with <open> and enter text in its buffer.

~ $ 

Eshell commands are Emacs functions, e.g,.

(defun kitty (buffer)
  (with-current-buffer buffer
    (buffer-string)))
~ $ kitty #<*scratch*> | nl
     1  ;; This buffer is for text that is not saved, and for Lisp evaluation.
     2  ;; To create a file, visit it with <open> and enter text in its buffer.

     3  (defun kitty (buffer)
     4    (with-current-buffer buffer
     5      (buffer-string)))
~ $ 

here is another way to write an eshell command, then you can invoke it via your-cat in eshell:

(defun eshell/your-cat (&rest args)
  (if (bufferp (car args))
      (with-current-buffer (car args)
        (buffer-string))
    (apply #'eshell/cat args)))
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • Just to clarify, could I also make `kitty` a `eshell`-only command be better by defining it as `eshell/kitty`? Also, could you help modify `kitty` to call cat if called with a filename and cat a buffer if called with a buffer name. I will try to do it myself and post it here but I am not good with lisp. – GenaU Jan 08 '20 at 11:56
  • 1
    @GenaU Yes, the Emacs function named `eshell/foo` can be invoked as `foo` in Eshell. You can use `bufferp` to test if the argument is a buffer, if it's not, you can fallback to `eshell/cat`, e.g., `(defun eshell/your-cat (&rest args) (if (bufferp (car args)) (cat-buffer ...) (apply #'eshell/cat args)))`. – xuchunyang Jan 08 '20 at 12:59