[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Can Emacs pipe a buffer through another one?
From: |
Marco Parrone |
Subject: |
Re: Can Emacs pipe a buffer through another one? |
Date: |
Thu, 17 Jun 2004 23:53:35 GMT |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) |
J Krugman on Thu, 17 Jun 2004 21:09:47 +0000 (UTC) writes:
> Suppose I have two buffers A and B, not necessarily associated with
> a file on disk, and furthermore, suppose that B's content is a
> script (bash, perl, python, etc.) that prints to STDOUT a transform
> of whatever it reads from STDIN. (Assume that the first line of
> B is a suitable shebang line.) It would be really cool if, without
> leaving Emacs, and without creating any new files on disk, one
> could feed the contents of buffer A as STDIN to the script in buffer
> B, and take the resulting output and insert them in some other
> buffer C (possibly replacing some or all of C's contents). (Of
> course, there should be no reason why these buffers should all be
> different from each other. For instance, B could be a script that
> rewrites itself.)
>
> Even cooler would be if instead of using whole buffers for program
> and data as described above, one could use regions.
>
> Can one already do any of this in Emacs? If not, can someone give
> me a clue about how to write such a thing in Emacs Lisp?
If creating a temporary file is not a problem, than it's not so hard.
A good way to do it is to try to do it interactively, then figuring
out what functions you have used (using `C-h k KEY'), and write an
elisp version with the help of the elisp manual and the help and
apropos functions.
However, a quick-and-dirty version follows:
(defun shbufwrap (scriptbuf inbuf outbuf)
(let* ((prefix "/tmp/")
(filename (concat "shbufwrap-" (number-to-string (random 1000))))
(path (concat prefix filename)))
(save-excursion
(with-current-buffer scriptbuf
(kill-ring-save (point-min) (point-max)))
(find-file path)
(with-current-buffer filename
(yank)
(save-buffer))
(shell-command (concat "chmod +x " path))
(with-current-buffer outbuf
(kill-region (point-min) (point-max)))
(with-current-buffer inbuf
(shell-command-on-region (point-min) (point-max) path outbuf))
(kill-buffer filename)
(shell-command (concat "rm " path)))))
This requires that inbuf and outbuf are not the same buffer. To test it:
eval the previous defun (for example, copy it into the *scratch*
buffer, then do C-x C-e after the last closed paren), then
C-x 1
C-x b *a*
C-x 2
C-x b *b*
something (text inserted in the *b* buffer)
C-x 2
C-x b *c* (from here to M-: is text inserted in the *c* buffer)
#!/bin/sh
cat /dev/stdin | sed s,something,somethingelse,g
M-: (shbufwrap "*c*" "*b*" "*a*")
Then you should have "somethingelse" in the "*a*" buffer.
You can hack it to make it interactive (for example, you can modify it
so you can do M-x shbufwrap, and it asks the buffers names).
If you want to make it to replace the input buffer, you can replace
(shell-command-on-region (point-min) (point-max) path outbuf)
with
(shell-command-on-region (point-min) (point-max) path nil t)
and
(defun shbufwrap (scriptbuf inbuf outbuf)
with
(defun shbufwrap (scriptbuf inbuf)
and you remove
(with-current-buffer outbuf
(kill-region (point-min) (point-max)))
in the above function (and call it using `M-: (shbufwrap "*c*" "*b*")').
However perhaps `C-u M-| COMMAND' is fine for you (it executes a shell
command on a region, replacing its content).
The `shbufwrap' version involving regions is more interesting, if I
will have it working I will post it in this thread.
--
Marco Parrone <marc0@autistici.org> [0x45070AD6]
pgpgSS_ToNYnZ.pgp
Description: PGP signature
Re: Can Emacs pipe a buffer through another one?,
Marco Parrone <=