emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Teaching emacsclient to act as a pager, and more


From: Spencer Baugh
Subject: Teaching emacsclient to act as a pager, and more
Date: Mon, 6 Jun 2016 21:25:01 -0400

Hi emacs-devel,

I've added the ability for emacsclient to act as a pager, such that
you can pipe data to emacsclient and page through it in the emacs
frame of your choice. The attached patches are on top of commit
549470fdf234acb4da7941e3bb9b28ed63a51876

Here is a video demo: https://catern.com/files/emacspager.webm

To do this, I've used the file descriptor passing feature of Unix
sockets, which allows a process to transmit a duplicate of any of its
open file descriptors over a Unix socket to another process. The other
process can then make full use of that file descriptor, including, of
course, reading and writing from it.

In the attached patches, I taught emacsclient to (when a new option
--pipeline/-l is passed) send its stdin/stdout/stderr to the emacs
server, and I taught the emacs server to accept those file descriptors
and make an Elisp process out of them. Then the process machinery does
the rest of the work of reading data from the Elisp process (which is
actually data coming in on emacsclient's stdin) and putting it in a
buffer.

This functionality is exposed to Elisp by simply directly passing
received file descriptor numbers to the process filter function (with
a new argument, to processes that have opted in with a new keyword
argument :ancillary). Those file descriptor numbers can be passed to a
new function make-fd-process.

I've written a function in Elisp, server-pager, which should be run
with emacsclient -l --eval (server-pager). I added a new dynamic
variable server-emacsclient-proc which is non-nil if we are currently
evaluating Lisp for an emacsclient, and holds the Elisp process
corresponding to that Emacsclient. server-pager uses this variable to
retrieve the file descriptors for the current emacs-client, invoke
make-fd-process, and pop-to-buffer the output buffer. server-pager
stores the Elisp process it creates in the plist of the corresponding
emacsclient, so when the Elisp process is killed, emacsclient is told
to exit (if it didn't also open frames). Likewise if emacsclient is
killed, the server-pager Elisp process is killed.

The primary issue here, it seems to me, is that this leads to huge
amounts of file descriptor leakage - if any passed-in file descriptor
is unused, it is eternally left open. I think a good way to fix this
is to add a native Elisp file descriptor type, so the file descriptor
can be closed on garbage collect. But perhaps there's a better
solution? In any case I would need guidance on how to create such a
new Elisp type - this is my first attempt to hack on the Emacs C
codebase.

I am sure that these patches are terrible style, not in keeping with
the Emacs coding conventions, and totally unportable (I wrote this on
GNU/Linux) - I just wanted to get out a quick proof of concept.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]