I've been using GNU Emacs since (I believe) fall of 1986, when the Stanford CS department got its first VAX 8600, or rather it's first Large UNIX host that was big enough to host all of the grad students (a machine for which we spent months and months arguing over what to name it(1)).
I will probably die in an Emacs buffer.
I've written any number of emacs-lisp utilities over the years, most of which have been superceded in some way, as younger programmers fix all of the crap that their elders leave behind. But there are still a few I still seem to use regularly. On this page we have:
bdiff.el | diff a buffer with the file it's visiting |
mud-mcp.el | connect to MUDs (supporting MCP features) |
(SO_KEEPALIVE hack) | a useful emacs-networking trick independent of MCP or MUDs |
tinydns.el | maintain your DNS "zone" files for tinydns. |
bdiff.el
This one's really stupid. You'd think these would be core Emacs functions by now. For all I know maybe they are and I just haven't found them yet. At this point there's probably stuff in Emacs that even RMS doesn't know about.
I wrote this in 1992 for Emacs 19 and it's the one thing I still use all the time 30 years later (well okay, I perhaps use it less when I'm in .git
-world and there are all kinds of weird diff
options available, but that's a fairly recent development):
M-x bdiff
diff
the current buffer with the file being visited. With a ^U^U
prefix argument, diffs with the autosave file instead.M-x list-munged-buffers
list-buffers
style listing of all file buffers that have been modified behind our backs.M-x list-unsaved-buffers
list-buffers
style listing of all file buffers that have been modified (by us)."
This also inserts some useful keystrokes into the buffer menu c
to run bdiff
on a file buffer there and R
to revert. (I'm guessing this violates some MELPA convention on how to do packages, which is the part of why I haven't submitted this that one can't attribute to simple laziness; oh well…)
mud-mcp.el
People keep asking for my mud.el
. Truth be told, I don't have one.
Background: mud.el
was a rather popular package for MUDding in the early 90s that existed in many different versions, mainly, I believe, because at the time it was written comint.el
didn't exist yet or the original author didn't know about it.
What I do have is an Mud Client Protocol (MCP) implementation. If you're reading the MOO programmers manual and seeing the PREFIX
and SUFFIX
commands (horribly broken ever since Pavel implemented suspend()
; Do Not Use) and wondering what the more modern—meaning circa 1997 instead of circa 1992—way is of multiplexing your connection so that you can be talking in The Living Room and editing verbs/descriptions-of-things at the same time, that is essentially the sort of thing that MCP is for.
MCP is perhaps a dead protocol (though I've had people argue that it's really more stillborn than dead)—the group that wrote it has long disbanded and AT&T recycled the mailing list archive when Dave left—but it was used a lot on JHM, became an essential feature of JHCore, has been incorporated into a number of clients (e.g., TinyFugue) and is still in use in at least a few places (e.g., Waterpoint). (I believe somebody ported it to LambdaMOO at some point, but it is not enabled by default).
For more on MCP, aside from the main page already referenced above, there is also my MCP page with some discussion of the protocol's dark corners along with a more complete set of emacs lisp files you'll need if you actually want to use the protocol,…
…and also some (Truly Ancient) implementations in Java (1.3.1) and Perl (5.6).
Anyway, in the process of writing mud-mcp.el
, I discovered comint.el
(a generalized "terminal mode") existed, did pretty much all of the things mud.el
did but better—never mind that comint
has actually been maintained and improved over the proceeding 20 years—and so I put in a few dozen lines at the end to provide functions to connect to a MUD using comint.el
.
And so, that's what I use, to this day, to talk to MUDs. You can, too even if you don't care about MCP.
What you'll need is the main elisp file, to be installed in your load-path
somewhere and then a mud-sites.el
file, listing your favorite places, e.g.,
(defconst mud-sites '( ;;;(With so many sites going up and down all the time, this list ;;; should really be read from someplace more volatile than an emacs ;;; library file. -- SMC) ;;; ;;; SERVER NAME MUD SITE PORT ;;; ("LambdaMOO" MOO "lambda.moo.mud.org" 8888) ;;; ... ))
… and yes, that comment is indeed faithfully reproduced from my current mud-sites.el
file. I have no idea who "SMC" is. What's ironic about it is I have about 42 not-commented-out lines in my file, and excluding the ones that are dead and long gone, we're left with five (LambdaMOO, Waterpoint, OpalMOO, YibMOO, DownMOO) that, as of today (9/12/2024), are still running (at least in some sense of the word; I have not signed into all of them anything like recently) and have thus been up for decades. Go figure.
The "MUD" column is an artifact left over from mud.el
which had drivers to implement special features for particular MUD types (e.g., LPMUD, TinyMUSH,…). mud-mcp.el
does not know about any of that, the 2nd column is ignored, so you can have pretty much whatever you want there.
Once you have the two files installed, mud-mcp.el
and mud-sites.el
, you just need to load the first one (or put (requre 'mud-mcp)
in your .emacs
file) and then do
M-x mud-mcp-connect
and you're off to the races. Also, see the following item:
open-network-connection
SO_KEEPALIVE
hack
(This isn't really a file. It's just a few random lines of code you can slip into your .emacs
that you can do independently of whether you use mud-mcp.el
or not, … at least until they get around to implementing something like this in mainline Emacs, is.)
If, like me, you get annoyed at having your long-term connections constantly dropped, this (something you can put in your .emacs
or a file that it loads) could help, at least for connections that originate from within Emacs:
(defvar network-stream-keep-alive t "If true, calls to make-network-process will include a (:keepalive t) setting. Otherwise, make-network-process behaves in the default manner.") (define-advice make-network-process (:filter-args (args) keep-alive) (if network-stream-keep-alive (cons :keepalive (cons t args)) args))
FYI make-network-process
, as of a few Emacs versions ago, is how open-network-connection
is implemented under the hood. So, among other things, this advice will activate whenever you do a mud-mcp-connect
at a time when network-stream-keep-alive
is true, but this is not specific to mud-mcp-connect
.
Note that as a matter of general principle, you should not use advice
. It tends to mess with things that the folks who wrote the code don't normally expect to get messed with, and I will highly encourage you to read the section of the GNU Emacs Lisp manual that pertains to advice and why you generally need to be careful about using it.
This one, however, is pretty simple and make-network-process
is sufficiently low-level (read: a whole lot of shit depending on it) that changes in that interface should be few and far between. Also it's a function that takes only keyword arguments (i.e., ordering does not matter), so there are all manner of changes they could make to that API and this will likely still work (one of the advantages of keyword arguments). But do not take this as any kind of promise.
What it does is set the SO_KEEPALIVE
flag on the underlying socket. This means every so often a blank packet will get sent to tell the intevening gateways that yes, somebody is still using this connection, so please don't drop it. How fastidiously they'll honor this request will depend mostly on the respective network environments where you and whoever you're connecting to are. If one of you has an asshole ISP that doesn't like lots of idle connections, they may just indiscriminately kill them anyway from time to time, in which case you just lose.
Whether the default on network-stream-keep-alive
should be t
or nil
in your case is something you should give at least a small amount of thought to (e.g., if most of your connections aren't long term things you care about you may want it nil
,… but then you will have to remember to set it t
right before opening any connection you want kept alive).
tinydns.el
This is a major mode for editing tinydns
data files.
Background: tinydns
is a component of Daniel Bernstein's djbdns suite of DNS servers and utilities. At one time, tinydns
was the 2nd or 3rd most popular DNS server in use, depending on how you want to count things, and considered to be one of the more reliable and secure implementations out there. Admittedly, I don't know the current state of things. In 2007, DJB threw in the towel on maintaining it himself and released the code into the public domain. Given how widespread it was, I'm guessing there were any number of people intent on keeping it going, and I know the Debian folks, at least, continue to maintain their own fork.
In any case, I myself continue to use it for my stuff, due mainly to inertia.
The file format for tinydns
is arcane and weird. DJB seems to like having his configuration files be as terse as possible; in this case, each line starts with a single-letter command; so much fun. I'll grant that the standard BIND syntax for DNS zones is strange enough, you probably could count DJB's version as a win because it's shorter and there are fewer edits you have to do to accomplish many of the common tasks.
Anyway, I wrote a mode for editing it. Something to help me remember wtf is what, given that I edit DNS files on average once every five years, and, in this case, every keystroke matters.
If you run a tinydns
server you might want to use it, or you might not.
(1)Yes, once upon a time, people cared about machine names. We also fought about naming conventions; there was a California-place-names convention that many of the Stanford CS departement groups followed (yielding names like shasta
, labrea
, umunhum
,…), that some of us were getting tired of, and anyway this box was going to be Special.
For this particular box, we eventually decided on polya
, after Hungarian mathematician George Pólya). We used for maybe all of a year or two, and then it suddenly got "too expensive to maintain"; apparently, even though the machine itself was a donation from some company, the expenses to keep it going were not. I'm also guessing some grant funding ran out, at which point the grad students were then moved to neon
, a "hot spares" box—meaning it could be cannibalized for parts at any time if Something More Important needed fixing,—the name being due to some random convention the CS Facilities folks had for naming their hot spares boxes—I believe argon
and krypton
were also in use at various times.
Later on, xenon
replaced neon
, as the department eventually figured out they'd do better funding a commmon student computing space directly rather than relying on specific grants that kept disappearing. And then, as disk space and hardware got progressively cheaper, they decided all of the alumni could live there, too (and also that they could keep their accounts forever which was something of a bold move at the time). So that's where all of my Stanford stuff has lived for the past 30 years.
On "xenon
". Isn't it great that we spent all of that time and effort debating what to name polya
?