all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Can Emacs pipe a buffer through another one?
@ 2004-06-17 21:09 J Krugman
  2004-06-17 21:25 ` Barry Margolin
  2004-06-17 23:53 ` Marco Parrone
  0 siblings, 2 replies; 8+ messages in thread
From: J Krugman @ 2004-06-17 21:09 UTC (permalink / raw)





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?

Thanks!

jill

-- 
To  s&e^n]d  me  m~a}i]l  r%e*m?o\v[e  bit from my a|d)d:r{e:s]s.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-17 21:09 Can Emacs pipe a buffer through another one? J Krugman
@ 2004-06-17 21:25 ` Barry Margolin
  2004-06-18  2:45   ` J Krugman
  2004-06-17 23:53 ` Marco Parrone
  1 sibling, 1 reply; 8+ messages in thread
From: Barry Margolin @ 2004-06-17 21:25 UTC (permalink / raw)


In article <cat1ar$c18$1@reader2.panix.com>,
 J Krugman <jkrugman345@yahbitoo.com> wrote:

> 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?

I can't think of any way this could be done.  If the script isn't put in 
a file, then the way to feed the script to the interpreter would be 
through its stdin.  But if the interpreter is reading the script on 
stdin, then where will it read the data from?

This might have been possible if Unix also supported "interpin", i.e. a 
standard descriptor that's used by interpreters to read their scripts.  
In that case, the script buffer would be piped to the subprocess's 
interpin, while the data buffer would be piped to the subprocess's stdin.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-17 21:09 Can Emacs pipe a buffer through another one? J Krugman
  2004-06-17 21:25 ` Barry Margolin
@ 2004-06-17 23:53 ` Marco Parrone
  1 sibling, 0 replies; 8+ messages in thread
From: Marco Parrone @ 2004-06-17 23:53 UTC (permalink / raw)



[-- Attachment #1.1: Type: text/plain, Size: 3454 bytes --]

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]

[-- Attachment #1.2: Type: application/pgp-signature, Size: 188 bytes --]

[-- Attachment #2: Type: text/plain, Size: 152 bytes --]

_______________________________________________
Help-gnu-emacs mailing list
Help-gnu-emacs@gnu.org
http://lists.gnu.org/mailman/listinfo/help-gnu-emacs

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-17 21:25 ` Barry Margolin
@ 2004-06-18  2:45   ` J Krugman
  2004-06-18 15:24     ` Kevin Rodgers
  0 siblings, 1 reply; 8+ messages in thread
From: J Krugman @ 2004-06-18  2:45 UTC (permalink / raw)


In <barmar-6C3FE7.17253017062004@comcast.dca.giganews.com> Barry Margolin <barmar@alum.mit.edu> writes:

>In article <cat1ar$c18$1@reader2.panix.com>,
> J Krugman <jkrugman345@yahbitoo.com> wrote:

>> 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?

>I can't think of any way this could be done.  If the script isn't put in 
>a file, then the way to feed the script to the interpreter would be 
>through its stdin.  But if the interpreter is reading the script on 
>stdin, then where will it read the data from?

Perl at least will let one give it code as the argument to the -e
flag, which leaves STDIN available for input.  For bash apparently
something similar holds for the -c flag (but I have no experience
with it).  I imagine other scripting languages have similar
mechanisms.  Anyway, as long as the interpreter reads the entire
script before it executes it (and I don't know of any interpreted
language for which this isn't the case), then STDIN could serve
both for feeding the script to the interpreter, and then feeding
input to the running script[1].  The two tasks do not overlap in time,
so it should be possible to accommodate both, no?

jill

[1] I imagine that threading could complicate this picture, but I
don't know much about threading, and I doubt that threading would
be a particularly popular thing to do for the kind of scripts we
are talking about here.

-- 
To  s&e^n]d  me  m~a}i]l  r%e*m?o\v[e  bit from my a|d)d:r{e:s]s.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-18  2:45   ` J Krugman
@ 2004-06-18 15:24     ` Kevin Rodgers
  2004-06-20 19:16       ` J Krugman
  0 siblings, 1 reply; 8+ messages in thread
From: Kevin Rodgers @ 2004-06-18 15:24 UTC (permalink / raw)


J Krugman wrote:
 > In <barmar-6C3FE7.17253017062004@comcast.dca.giganews.com> Barry Margolin <barmar@alum.mit.edu> writes:
 >>In article <cat1ar$c18$1@reader2.panix.com>,
 >>J Krugman <jkrugman345@yahbitoo.com> wrote:
 >
 >>>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?
 >
 >>I can't think of any way this could be done.  If the script isn't put in
 >>a file, then the way to feed the script to the interpreter would be
 >>through its stdin.  But if the interpreter is reading the script on
 >>stdin, then where will it read the data from?
 >
 > Perl at least will let one give it code as the argument to the -e
 > flag, which leaves STDIN available for input.  For bash apparently
 > something similar holds for the -c flag (but I have no experience
 > with it).  I imagine other scripting languages have similar
 > mechanisms.  Anyway, as long as the interpreter reads the entire
 > script before it executes it (and I don't know of any interpreted
 > language for which this isn't the case), then STDIN could serve
 > both for feeding the script to the interpreter, and then feeding
 > input to the running script[1].  The two tasks do not overlap in time,
 > so it should be possible to accommodate both, no?

Cool!

(with-current-buffer (get-buffer "A")
   (shell-command-on-region (point-min)
                            (point-max)
                            (with-current-buffer (get-buffer "B")
                              (buffer-string))
                            (get-buffer "C")))

-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-18 15:24     ` Kevin Rodgers
@ 2004-06-20 19:16       ` J Krugman
  2004-06-21 18:32         ` Kevin Rodgers
  0 siblings, 1 reply; 8+ messages in thread
From: J Krugman @ 2004-06-20 19:16 UTC (permalink / raw)


In <40D30930.6090309@yahoo.com> Kevin Rodgers <ihs_4664@yahoo.com> writes:

>J Krugman wrote:
> > In <barmar-6C3FE7.17253017062004@comcast.dca.giganews.com> Barry Margolin <barmar@alum.mit.edu> writes:
> >>In article <cat1ar$c18$1@reader2.panix.com>,
> >>J Krugman <jkrugman345@yahbitoo.com> wrote:
> >
> >>>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?
> >
> >>I can't think of any way this could be done.  If the script isn't put in
> >>a file, then the way to feed the script to the interpreter would be
> >>through its stdin.  But if the interpreter is reading the script on
> >>stdin, then where will it read the data from?
> >
> > Perl at least will let one give it code as the argument to the -e
> > flag, which leaves STDIN available for input.  For bash apparently
> > something similar holds for the -c flag (but I have no experience
> > with it).  I imagine other scripting languages have similar
> > mechanisms.  Anyway, as long as the interpreter reads the entire
> > script before it executes it (and I don't know of any interpreted
> > language for which this isn't the case), then STDIN could serve
> > both for feeding the script to the interpreter, and then feeding
> > input to the running script[1].  The two tasks do not overlap in time,
> > so it should be possible to accommodate both, no?

>Cool!

>(with-current-buffer (get-buffer "A")
>   (shell-command-on-region (point-min)
>                            (point-max)
>                            (with-current-buffer (get-buffer "B")
>                              (buffer-string))
>                            (get-buffer "C")))

You lost me there!  I don't see how this could possibly do what I
described.  Can you give me an example of how to use this?

jill



-- 
To  s&e^n]d  me  m~a}i]l  r%e*m?o\v[e  bit from my a|d)d:r{e:s]s.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-20 19:16       ` J Krugman
@ 2004-06-21 18:32         ` Kevin Rodgers
  2004-06-21 20:19           ` Kevin Rodgers
  0 siblings, 1 reply; 8+ messages in thread
From: Kevin Rodgers @ 2004-06-21 18:32 UTC (permalink / raw)


J Krugman wrote:
 > In <40D30930.6090309@yahoo.com> Kevin Rodgers <ihs_4664@yahoo.com> writes:
 >>J Krugman wrote:
 >>>Perl at least will let one give it code as the argument to the -e
 >>>flag, which leaves STDIN available for input.  For bash apparently
 >>>something similar holds for the -c flag (but I have no experience
 >>>with it).  I imagine other scripting languages have similar
 >>>mechanisms.  Anyway, as long as the interpreter reads the entire
 >>>script before it executes it (and I don't know of any interpreted
 >>>language for which this isn't the case), then STDIN could serve
 >>>both for feeding the script to the interpreter, and then feeding
 >>>input to the running script[1].  The two tasks do not overlap in time,
 >>>so it should be possible to accommodate both, no?
 >
 >>Cool!
 >>
 >>(with-current-buffer (get-buffer "A")
 >>  (shell-command-on-region (point-min)
 >>                           (point-max)
 >>                           (with-current-buffer (get-buffer "B")
 >>                             (buffer-string))
 >>                           (get-buffer "C")))
 >>
 >
 > You lost me there!  I don't see how this could possibly do what I
 > described.

You want buffer A's contents passed as standard input to the script in
buffer B, with the output going to buffer C.  So:

a. First select buffer buffer A, and pass its contents as standard input
    to a shell command whose output goes to buffer C.

b. The shell command comes from the contents of buffer B, which is
    passed via the -c option to the shell.

`C-h f shell-command-on-region' et al.

 > Can you give me an example of how to use this?

Here's what I did:

1. Create buffer A with `C-x b A', and put some text in it:
one
two
three

2. Create buffer B with `C-x b B', and put a simple script in it:
cd ~; pwd
wc
cd /tmp; pwd

3. Create buffer C with `C-x b C'.  This step could be avoided by using
    (get-buffer-create "C") instead of (get-buffer "C").

4. Copy-and-paste the above form in the *scratch* buffer, and type `C-x
    C-e' or `C-j' (see the "Lisp Interaction" and "Lisp Eval" nodes in
    the Emacs manual).

5. Buffer C now contains:
/home/kevinr
        3       6      28
/tmp

-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can Emacs pipe a buffer through another one?
  2004-06-21 18:32         ` Kevin Rodgers
@ 2004-06-21 20:19           ` Kevin Rodgers
  0 siblings, 0 replies; 8+ messages in thread
From: Kevin Rodgers @ 2004-06-21 20:19 UTC (permalink / raw)


Kevin Rodgers wrote:
 > Here's what I did:
 >
 > 1. Create buffer A with `C-x b A', and put some text in it:
 > one
 > two
 > three

Actually, I used:
one
two three
four five six

 > 2. Create buffer B with `C-x b B', and put a simple script in it:
 > cd ~; pwd
 > wc
 > cd /tmp; pwd
 >
 > 3. Create buffer C with `C-x b C'.  This step could be avoided by using
 >    (get-buffer-create "C") instead of (get-buffer "C").
 >
 > 4. Copy-and-paste the above form in the *scratch* buffer, and type `C-x
 >    C-e' or `C-j' (see the "Lisp Interaction" and "Lisp Eval" nodes in
 >    the Emacs manual).
 >
 > 5. Buffer C now contains:
 > /home/kevinr
 >        3       6      28
 > /tmp

Hope the mismatch between (1) and (5) didn't confuse you.

-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-06-21 20:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-17 21:09 Can Emacs pipe a buffer through another one? J Krugman
2004-06-17 21:25 ` Barry Margolin
2004-06-18  2:45   ` J Krugman
2004-06-18 15:24     ` Kevin Rodgers
2004-06-20 19:16       ` J Krugman
2004-06-21 18:32         ` Kevin Rodgers
2004-06-21 20:19           ` Kevin Rodgers
2004-06-17 23:53 ` Marco Parrone

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.