Piping from GNU Screen to GNU Emacs

I’m continually discovering nifty new features of GNU Screen, and I’ve taken advantage of one of them to fix one of my long-standing annoyances with what’s otherwise a nearly-perfect piece of software – the rather awkward scroll-back buffer.

Here’s a method for essentially using Emacs as the scroll-back buffer (though convenient paste behaviour will have to come later):

First, create a named pipe in your home directory:

mkfifo ~/.screen.fifo

Then place the following shell script somewhere in your $PATH, calling it e.g. read-screen-fifo.sh:

#!/bin/bash

emacsclient -n -t -e '(shell-command "cat ~/.screen.fifo" "*screenfifo*")' &
#sleep 0.5
screen -X eval "hardcopy -h $HOME/.screen.fifo"
screen -X screen -t hardcopy 0 emacsclient -t -e '(switch-to-buffer "*screenfifo*")' -e '(goto-char (point-max))'

Then place the following binding in your .screenrc:

bind E exec read-screen-fifo.sh

Now, pressing your screen prefix key (C-a by default, back-tick for me) then E will result in screen opening an emacsclient frame containing the entire contents of the initial window’s scroll-back buffer.

Note that commented-out sleep – if Emacs is a bit slow off the mark reading from the fifo, screen can get very angry and appear to hang (albeit recoverable by reattaching); so you may want to give it a split-second to catch up. Also, I discovered that screen is also very picky about what it lets you run inside an eval, so watch out (hence this all being done with shell scripts). This may be because screen will refuse to write to the fifo until there’s another program already reading from it – this is different from the behaviour of, say, cat.

Bonus screen trick I discovered in the course of this: put bind R source ~/.screenrc in your .screenrc to give yourself a way of reloading screen without the need for a restart (came in very handy when working out the above – I actually managed to completely crash Emacs three times, but Screen only tended to hang, in a recoverable way).