This one's worth watching — it's a live screen-share, and the fun is seeing the keystrokes fly. The transcript below is a lightly-edited companion for reading or searching; every word is Steve's.

Hey everybody, and welcome back to Stevey's Tech Talk. This week I don't have a guest lined up, so I'm going to do something new and a little bit different for me. I've figured out how to get OBS to do display capture, so I'm going to do a guided tour of Emacs.

I'm going to show you some of its features, and how Emacs approaches things, and I'm going to show off a bunch of little mini-applications inside of Emacs and talk about some of the editing facilities that you won't find anywhere else. I'm going to do it all as I sit there in real time. I apologize if you're on the podcast and you can't see what I'm doing — I do my absolute best to narrate everything that I'm doing. Generally speaking, Emacs is fast enough that you can do it as you're narrating it. So just imagine what it's going to be like, and if you like the content, then come back and watch this YouTube episode.

So we'll get to it shortly, but I just want to remind you that if you like this content and you want to see more of it — more guests, more episodes, and you want the show to go on — then all you've got to do is like it and subscribe to the channel, and YouTube takes care of the rest for us. So with that, let's get started.

All right. We are officially looking at Emacs. Hope you guys can see this. This is not normally the aspect ratio that I run Emacs at — usually I run it very tall and kind of narrow, but because of the screen recording limitations, it looks like it's going to be best if I run Emacs looking sort of like a terminal here.

So what are we looking at here? Emacs looks kind of like a shell. In fact, it even says "shell" here at the top, and it says "shell" here at the bottom, on this line right near the bottom called the mode line. The mode line shows a bunch of information about the buffer that you're currently looking at.

Now, everything in Emacs is a buffer. This is a very different philosophy than most programming environments, or even productivity environments like Xcode or Final Cut Pro, or any sort of development environment. They usually have a couple of different dedicated areas, right? One for your code, or for a timeline, or for a preview, or for a directory browser or whatever. And then they have a whole bunch of menus, and they're all special-purpose — they're all custom UI.

In Emacs, everything is treated very, very consistently. As you can see, what I'm looking at right now is two buffers, and I'm switching back and forth between them. The one on top is a shell. It's just like a regular terminal shell, except it's an Emacs shell, so it's implemented in Lisp. It doesn't have all of the VT100 codes, so there are certain things — if you try to run something like top, you're going to get strange output. But you can run regular Unix commands and it'll dump all the output. And because it's an Emacs buffer, it's just like the kind of editing area that you'd have for your source code.

All this shell output — boy, I had a lot of processes running. No idea why so many processes are running on this machine. But as you can see, it's just like a regular buffer. I can move the cursor around in it, I can cut and copy things, I can select regions, I can do pretty much any editing command on the shell output.

Which is great, because if I do a command — like here I'll do an ls and look at the directories I'm in. Currently I'm in my game directory for my online game, and it looks just like a regular shell. But if I go up, I can grab a command, bring it back down again, paste it, and then modify it before I execute it again. So you can still use the standard shell commands like normal, but it's really powerful to be able to take this hunk of text — that came out of this directory listing — go to a temporary buffer, give it a name (I just called it asdf), and start editing it.

I can sort the lines. Or I can delete a whole column — let's get rid of this column right here, and all these DVDs disappeared. And let's make all the staffs disappear too. Boom. So as far as text editing goes, it's very, very powerful. I can write little bitty macros and stuff to start making modifications, like the ones I'm doing as you're watching — I've just been doing a whole bunch of very fine-tuned little edits.

So basically the philosophy of Emacs is: everything is a buffer. Well, what do I mean by everything? We can run the calendar, and look — it says February, March, and April. The cursor moves from day to day, and I can even see all the different holidays from a bunch of different systems. If I hit H on February 14th, it tells me it's Valentine's Day. So this is a buffer, which means the text is all editable. You can have read-only buffers, but you can always mark them as not read-only, and it means all the Emacs editing commands are available.

Another example of a buffer is a scientific calculator. Oops, I just said "calendar" again — Calc, the scientific calculator. As you can see, this one is two buffers down at the bottom of my screen. One is the actual calculator, so I can put a bunch of numbers in, and then I can stack them, and then I can start hitting plus and times and whatever. And I can see the entire history on the right side here of all the intermediate results. It's a very powerful scientific calculator. Right now I'm hitting the question-mark key and it's telling me what all the key bindings are — for sine, cosine, exponentials, pi, whatever. So it's a really cool calculator.

But the coolest thing about it is, what if I just wanted to go up to this buffer here and take these numbers right here? What I'm going to do is kill this column. You can deal with columns of numbers just as easily as rows, and columns of text just as easily as rows, in Emacs. I can put them here, and look — I just pasted them all into the calculator. They pasted kind of funny, but let's see if they add up. Oh yeah, they do. I can add them all up. So I just added up all the file sizes of those last ten files I listed in my directory, by pasting text from one buffer into a temporary buffer here — I didn't have to, but I wanted to see if it needed any cleanup first — and then I pasted it into the scientific calculator and I've got my results. Really pretty cool.

Similarly, the list of open buffers is itself a buffer. So here I'm looking at effectively all of the open tabs that I have in this Emacs session. As you can see, a lot of them — twenty-plus — are shells. Why do I have so many shells open? Well, they're all named. Here's one for the server, and as you can see, it's in the server directory.

What I did was I set up a function called wyvern-init, which initializes all the stuff I want to open in Emacs. It just goes and opens up a bunch of files and a bunch of directories, because I'm always visiting stuff in these directories — like sandbox. This is for my sandbox server, which is where the builders and architects of the game go and test stuff out before it goes live. So it's like a staging server.

So each one of these shells is its own process, and it's running in Emacs, and I can copy and paste stuff between them all. I can make modifications. If I want to change all these us-central-1b to us-central-1c — for whatever reason, maybe I'm writing a document and I want them to show up differently in the doc than they did in the listing — I can just say, this string central-1b to central-1c, and boom, just change them all inside of a shell buffer.

This is a running shell. I can still do commands here in the shell, but the text all up above is all editable. And it's kind of cool because it knows where the prompt is — my command prompt is set up so that it shows the directory that I'm in. I can go back up to older commands and hit Enter, or even modify them and hit Enter, and the commands are all available. So you can go all the way back into very long command histories, find very old commands that you've written — like this one right here, which does a build; it's an alias — and run them again. Boom. It copies it down to the bottom and starts my build again. And here's the Gradle build output.

Okay, you say, well, this doesn't sound all that exciting. It's got a calculator, it's got a calendar, there's all kinds of things. Basically, you can write apps for Emacs, and it's quite easy to do. Like, for example, the old push-a-ball game Sokoban. Let's install that. So I do package-install and then I say sokoban. I don't have it installed here. It's contacting the host. It brought in two files, and it installed rather quickly while my build was running in the background — as you saw, my Gradle build just completed successfully.

So now if I run Sokoban, the command — notice the commands are going in the very bottom here. That's called the minibuffer. It is also a buffer. It is editable. I can move around in it, or I can treat it like any other buffer; I can copy text in and out of it. But it is a little bit special, because it's where all of your input and some of your output goes.

You see how it says "no goal column" there at the bottom? Just as a segue: I have a nervous tic. I am constantly unsetting the goal column. The goal column is — let's say it's kind of like multi-cursors. If I always want the cursor to go to this column right here where I've got it, then I can hit Control-X Control-N, and now I have a goal column of 14. So now whenever I move the cursor onto the next line, it always goes to that column, which is useful if I want to put something right at the beginning of each whatever. (You can actually do real multi-cursors and so on.) Goal column is a very old concept. The problem is it's very easy to accidentally set a goal column, and it's annoying, so I'm always unsetting it, and it turned into a nervous tic. See how it says "no goal column"? Control-U Control-X Control-N. So yeah, that's my nervous tic when I'm in Emacs — I'm always unsetting the goal column, just to be sure there isn't one.

But those messages — where are they going? Well, if I go to a buffer called Messages, which is one of the built-in Emacs buffers, I can see every message that it's given me since I started this session. It's kind of handy, and it's also in a buffer, which means I can go grab it, copy the text out, go into a temporary buffer — which is just a scratch pad or workspace, I can put whatever I want there — paste the text in from this other buffer, and do the same sorts of things. I can sort the lines, I can filter the lines, I can list matching lines for "quit" and it'll show me which ones. And look, I did list matching lines for "quit," and the output is yet another buffer.

As you can see, buffers are responsive and reactive. They have their own mode. This mode is called Occur, which is listing occurrences of a particular pattern in some other buffer. So everything is first-class in Emacs — it's always a buffer. The output is never in some dialog box with its own fancy custom UI. It's always laid out in a buffer, because that means you can do all of the standard Emacs editing and searching and sorting and all the other options that are available to you on the output of some command, or on the output of some program.

So let's run that Sokoban game we installed earlier. Boom — now we have Sokoban, with really ugly graphics. But as you can see, we can push the blocks around. And the nice thing about Emacs is everything is customizable; the source code is all there, available to you. I can find the function sokoban — it's defined in sokoban.el, which we installed as a package just at the beginning of this video — and I can go there and visit it. Here it is, the Sokoban starting function that says what all the keys are, move left, move right. Notice it says sokoban-move-left, sokoban-move-right — those are commands that will actually move the little dude.

Let's go back to our Sokoban. So on the right-hand side I now have the Sokoban source code — there's some of it, this is all of it — and on the left I have the actual Sokoban game, with graphics and everything. They're terrible graphics. I could probably change them to be graphics from my game, which are a lot prettier, but whatever, it works. But hey, I'm used to playing Sokoban with the old H, J, K, L, semicolon keys, and unfortunately they are not bound for Sokoban.

Well, I can do it manually. I can say local-set-key, in this buffer — because every buffer has its own large data structure of all of the current configuration settings, the whole context specific to that buffer, including your key bindings. And I can say H to sokoban-move-left, which will autocomplete for me, and now I can use H to go left. But L still doesn't go right for me, so I'd have to local-set-key again, and say L is what command — sokoban-move-right. And now I can move left and right with my H and L keys, and I can also do up and down.

Well, if I wanted to do that permanently, let me show you what I'd do. I'd use the scratch buffer, which is a Lisp editing environment — it's very powerful — and I'd say eval-after-load sokoban, meaning run this after I load Sokoban. Or even better, maybe there's a hook. Let's search the Sokoban source code. There are no hooks — so they really messed this up. But it doesn't matter; Emacs is still very powerful and can let you do things. I'm saying eval-after-load sokoban, and then I'm going to do a bunch of statements — local-set-key H to sokoban-move-left, and so on, and do the rest of them — and then put this into a config file somewhere, one of my startup files. And it'll put in this little snippet of code where, after the Sokoban game is loaded, it runs my code that does modifications to the mode. In my case, I'd add four different key bindings. So it's very squishy and very flexible.

The Emacs shells, like I said, are not full VT100-compatible ANSI terminals — and that sort of defeats the purpose. They're squishy. Meaning, you run commands and you get the output, and then you have a lot of customization ability. You have a lot of ability to go back, scroll through the output, search through the output, copy and paste it. So I find that for most stuff, having lots of shells cd'd to the different directories is just a super great way to work.

And as you can see, the buffer list itself — the list of buffers, these are the open tabs — is a buffer. So again, all the motion commands and all the searching and editing commands apply. Plus, every buffer has its own mode — meaning the key bindings, and how it responds to the mouse, and how it colors things, and a bunch of other settings. In this case, the mode is called Buffer Menu. That's the major mode, the primary mode, for buffers that are your buffer list.

This is so much more scalable than tabs in a browser or tabs in an IDE, because they're sorted vertically, and you can actually see metadata for each one of the buffers. You can see the name of the buffer, and whether it's modified, and whether it's read-only. You can see the total memory size — how many bytes are in the buffer — and what mode it is. And if it's cd'd to a directory, what the current working directory of that buffer is. Really pretty cool. It can go on — you can get thousands of effectively open tabs. Normally you'd be on the order of hundreds; it'd be unlikely you'd have thousands, but you could in certain situations. And the thing is, that becomes completely unmanageable in an IDE, or really in any program that uses the tab model. I don't understand why people haven't stolen this — Emacs's model of everything being a buffer, and that including the UI for managing other buffers. It's something that only Emacs does well.

All right. One thing you can do here: you can see that I have a .gz file — a gzip file, it looks like an Emacs Lisp file — and I can just open it up. Oh, it says the buffer's been killed. Easy. So let me see if I can find another example. Let's go to documents and sort by zip. There's one. So what have we got here? We've got OBS LUT pack. What does that mean? A LUT is a lookup table — it's a filter for giving maybe cinematic effects to your video recording. OBS is the broadcasting studio software, open source, that I use. And right now we're looking at a zip file in Emacs, in a shell, looking at the documents directory.

We're going to go ahead and open it up. Well, what's inside of it? One cool thing is that we just opened a zip file inside of Emacs, and now we're peering at its contents. We have 79 files, a total of what looks like 71 megs. You can see all the file metadata inside of it. So it's got a nice zip browser, and it also works for bzip and tar.gz. It's a generalized mode called archive-mode, so any archive can be opened up in Emacs. And then not only can you see the entries, but you can actually open them. I can go and open this one up — and there it is, Emacs will show me the PNG file. Let me see if there are any binaries in here that aren't PNGs. There aren't.

So let's go find a different binary file, in the downloads directory — downloads is always likely to have some weird binary. Yeah, here's one. So let me show you something cool. I have one here — the GIMP, you know, the GNU image manipulation program. It's a very powerful editing program, very cool, a lot of fun; you should definitely learn it. It's like Photoshop. And this is the installer archive, so I'm just going to open it up. Boom. I've opened it up, it's parsed it, it's uncompressing it, it's reading all the entries in the zip — there are 154 entries all in all. As you can see, there's a bunch of dylib files, which is "dynamic library," so it's all compiled C code.

And I'm looking around inside of the archive. Well, I can actually open up one of these dylib files in Emacs. Why would you want to do that? If I just open it in raw mode, it's a bunch of gobbledygook, because these aren't renderable — they don't have Unicode characters or ASCII characters for all of these bytes inside this binary file. So normally you wouldn't want to do that. But every once in a while, if you're working with binary files in some format, you want to debug them. Well, you can run something called hexl-mode. And now look — Emacs has switched the way that we're viewing the file contents. You can see right here it says the mode is Hexl. So now we can actually see the strings inside of the binary, and they're all lined up on their byte boundaries. You can see where they start and end, and you can put the cursor on any byte and — check this out — you can actually edit the byte. I can go in and edit this binary and change this to a six, and a seven, 36, 37. You can edit the bytes. What I did was I stuffed the text "67" in there.

Now, if I were to save this — I'll just do it, because I'm not going to use that installer archive anymore. I just edited a binary file, and now I'm going to save it. And it says it's going to discard the undo info, is that okay? And I say yes. And it saved it. Not only did it save the binary file with my edits to it, but it can also write it back now into the archive that I opened it up from. And remember, this archive was for installing the game, but it had all of these files. Now I save the archive — boom, it's compressing it and blah, blah, blah. Very, very powerful.

Now, do you often want to go and edit binary files inside of archives? No. Has it been helpful at various points in my thirty-year career as a programmer? Yes. There it goes, it saved it — now it's officially corrupted. So I'll go ahead and delete the file, using the command delete-this-file. What does that mean? It means delete the file of the buffer that I'm visiting. So delete-this-file is not actually a built-in Emacs command, so let me show you how I did it. I'm going to say describe-function delete-this-file. And it says it's an interactive Lisp function in efuncs — which is "Emacs functions," a file I've been maintaining for 25-plus years, of a bunch of little helpers I've written. If you look at my Lisp directory, I have dozens and dozens of files of Emacs Lisp code that I've written that does all kinds of cool stuff.

delete-this-file is Lisp code, and this is what Emacs Lisp looks like. And I'll tell you — everybody's scared of Lisp, everybody's like, "Oh God, Lisp, it's really hard to read." And honestly, a lot of languages are hard to read. Perl is really hard to read. C++ is really hard to read. If you don't know the language, yeah, it's hard to read. But it turns out that Lisp is so regular, and actually so straightforward, that you can learn it very quickly, and you start looking at it as regular code — you'll see it just like Java. In fact, when I'm switching back and forth — I'm writing Lisp code that modifies Java and so on — sometimes you'll actually forget which language you're looking at, because you're really only looking at the identifiers and the symbols and the syntax highlighting. You have to squint at it and go, oh yeah, that's Lisp. So don't be afraid of Lisp. Lisp is the language that you use for config and for customizing Emacs.

Again, there's a scratch buffer that lets you play with expressions. I can evaluate two plus two and it says it's four — the evaluator works. And you can debug things. If I want to debug, say, this delete-this-file function — I just instrumented it for debugging with Control-X X. And now if I say delete-this-file, it goes into the Emacs debugger. There's a debugger, and look — I'm stepping through the expressions, and it's telling me the results. It's exactly what you need. You can see stack traces, you can put in error handlers, all that stuff. There's a profiler. All the programming tools that you'd want to be able to write your own Emacs code.

So ultimately what you have is this really powerful system where everything is in a buffer. That game, Sokoban, was inside of a buffer. Our buffer list is a buffer. We had a calendar and a calculator. And there are many, many other really cool applications written for Emacs — and I've written some of my own. For example, if we go back to my Elisp directory, we go up a directory and do LilyPond. I have a bunch of sheet music that I've been arranging. So if I look here at Kreisler page one, as you can see, I have this lovely formatted Preludium and Allegro in the style of Pugnani — actually, I'm going to be recording this soon. It's a guitar arrangement, and it has tab.

LilyPond outputs this from an input language called — well, it's the LilyPond markup language, it's a TeX language. I don't have LilyPond mode installed on this computer, because this particular computer is for my video recording. But as you can see, it's a markup language, sort of like XML and HTML and other markup languages — but this is a TeX language, and it shows which notes go in which measures, and which dynamic markings, and a bunch of other instructions on how to tell the formatter to format your beautiful sheet music.

Well, this was something I was doing for hours a day, and it went on and on. It's really hard to look at what we're looking at here in this buffer — the TeX language — and know what it's going to look like when it's formatted, like this. So what I did was, I basically created my own little IDE. As you can see, I have multiple frames open here; we don't have enough space to really show how it's going to look, but if I have them both open on a desktop, I can run a command — one that I wrote myself in Lisp — that will run the LilyPond compiler on the left-hand side code here, and if there are no errors, it'll refresh the PNG image of the actual formatted music on the right side. It's like a mini-IDE that I put together right inside of Emacs.

So Emacs gives you tremendous power and flexibility for writing custom workflows. And how often do you have to write a custom workflow? Well, any time you're doing something over and over and over again, you should start thinking: should I automate this? Is this something I do for my job every day? Automation can of course take the form of writing a program — that's kind of a lot of work — or you can write a script. Scripting is very helpful for writing automation, but Emacs gives you some even finer-grained and lighter-weight sorts of automation opportunities.

Let's do a live example here. I'm going to go to the content directory in my game, and we're going to open this directory up. It's the body-armor subdirectory — so it's all the built-in body armor. There are about 40 different kinds of armor: dragon mail, and cloak robes, and ring mails, and all that kind of stuff. And they're XML files, in a special mode. For starters, I defined this XML format as the way that I declare custom objects in my game. As you can see, it has its own image. If I hit Return, it's going to open that image — oh look, there it is, leather armor. If I open the dragon mail — blue dragon mail, green dragon mail — we open that image, and there's some green dragon armor.

So I had to teach Emacs what my directory structure was like, and where these classes are. I can click on the class and it'll open it up for me. And I did it by writing my own mode. I mentioned modes before — modes define the behavior of the buffer that you're looking at. Well, I wanted my mode to start as XML, so that it knows about XML close tags and formatting and things like that, but I also wanted to have extra functionality. For example, when I'm hitting the Return key on various things inside of my game object, I want it to take me to the appropriate file.

Let's see how I did it. If I describe the key — notice you can see all your key bindings in Emacs with Control-H B, and it'll put them all in a buffer, and as you can see, I have well over 1500 key bindings globally, overall, in Emacs. This is what they all are. So Emacs is super self-documenting. You can open up the Info buffer here. Info is a hyperlinked manual where you can learn all about different packages for Emacs — mail readers and news readers and Org mode and all that stuff, remote file editing, advanced directory editors, many, many powerful tools. And it's all hyperlinked, and it's all done in Emacs's unique style. It is a self-documenting editor — and because it predates the web, and besides, it's more powerful to have that stuff inside an Info buffer, because I want to take this text and do something with it. Like, take this text and throw it into a temporary buffer and sort the lines. I can do it. Super, super powerful.

So we're going to go back to our thing and look at the key binding for the Return key. Let's describe-key, Return key. And it says it's map-mode-follow-reference. So I wrote a mode called map-mode, for my game map files and archetype files, which are both XML. It's in a file called map-mode.el, Emacs Lisp. Here's all the code, and the follow-reference function is right here. As you can see, it's some Lisp code that basically says: if the point is over some sort of image path, or another archetype, or a class, then we're going to go ahead and open it up.

So let me tell you a little bit about Emacs's programming model. Emacs's programming model is very different from any other system I've ever seen before, because it treats it as if you were basically writing macros. You start with a cursor, and the cursor is a little busy bee that moves all over the buffer — and the cursor is you, you are the cursor. At any given time it's called point, and all the editing operations actually happen at point. So if you want to make an editing operation on line 39, you have to move the point there. So you'll do goto-line, or goto-char, or go to a character.

As you can see right here, I'm doing it. I call a macro called save-excursion multiple times in this big when statement: if we're on a map reference, do this; if we're on an image reference, do this; et cetera. And what I do is I save the excursion — and it really is an excursion, your little busy bee is going to go off somewhere on an adventure, and then when it's done you're going to come back to where you were. So inside of this XML file — I'll put these two things side by side, so you can see — inside the green dragon mail, my cursor's sitting here inside the image path, halfway along the path. Well, over here we're going to save-excursion, which means remember where the cursor is and a couple of other things, and then we're going to go to the point at the beginning of line. So we're going to go here, you see — and then if we're looking at an image ref, or a Christmas image ref (because we have Christmas images), then we're going to call this function map-mode-open-image on the first match, because "looking at" can take a regular expression.

Let's go look at that image ref real quick. I'll probably do a whole episode on programming in Emacs Lisp, that'd be kind of fun. But as you can see, I've defined a regular expression inside of a string here. It's not pretty. Regular expressions in Emacs are kind of more awkward than they should be, because the escaping isn't the best. They really need — Emacs Lisp really needs regular expression literals. That's one huge advantage that languages like, say, Kotlin have. But you can still do it, and the regexes are powerful — they have Perl-compatible regexes and all that. So basically I say: am I looking at some whitespace, followed by this image tag, followed by path-equals-whatever, followed by the image path? And then I slurp it up, and back in my code, in follow-reference, I say: well, if it's an image, we're going to call map-mode-open-image on it. So it's going to open it up, and I'm going to see the green dragon mail again. Again, I've made myself a little mini-IDE.

Now, I would love someday to do a plugin for IntelliJ that understands all of the custom stuff for my game code. I would love to, but that's a project — I've done IntelliJ and Android Studio plugins before, and they're very powerful, and you can do a lot, but it's like writing your own desktop application. Whereas this little function right here is just a couple of lines of code, and it does everything I need. And I've got it handling a whole bunch of cases — it can go to classes, it can go to other archetypes, the parent archetype, it can go to Python files, all that stuff.

So there's this sort of continuum, of small plugins all the way on up. For example, one thing that Emacs loves to do is beep. Emacs loves to beep at you. So eventually I wrote a little command called nobel — N-O-B-E-L, which means "no bell" — and I don't want it to beep at me anymore. So let's find: where is nobel? I don't even know what it is anymore, let's go look. It's in my Emacs functions. It turns off bell-ringing and bell-flashing, so that when I quit, it's not beeping and flashing at me. I'd read the docs, and it looks like all it does is set the ring-bell-function to a lambda that takes no arguments and returns nothing. So the ring-bell-function is a no-op. And I made it a little command with this keyword "interactive," and I added it in among my hundreds and hundreds of little commands. So now I can type M-x nobel if I want to turn the beeper off. That's really a full application, in literally four lines of code — one of which is the comment string, the documentation.

It's like HTML, right? With HTML, you can build a webpage with just a really basic markup. And then you can get a little more sophisticated and add in stylesheets, and then even more sophisticated and add in some JavaScript, and you can go on up from there and they become arbitrarily complex. But your basic HTML file is just a couple of lines of HTML and it can be formatted, marked up — it's really simple. And it's that simplicity, that learning curve that goes from the simple to the complex, that is utterly lacking in IDE environments. They start complex. If you're going to write a plugin for an IDE, prepare for your hello world to be days of learning and pages of code, just to do the hello world. Whereas in Emacs, I can install a menu entry or a new command — something that does something meaningful, a workflow for myself — with just a couple of lines of code stuffed into one of my config files.

And so over time you build a DSL for your life. As a programmer — actually, no, beyond programming. As we talked about before, I did a LilyPond thing. I've done automation for Final Cut Pro as well — I've started adding more and more Emacs functions to process files before I'm getting ready to do the editing and things like that. So it's just an incredibly powerful environment.

I want to show you one demo that I've mentioned a few times, because I think it's important. One claim I often make is that it's faster to use the keyboard than the mouse. So here we have a mouse, and we have the keyboard, and I want to go to this spot right here, 1203-1, or something that's sort of unique — this fir tree right here. And let's say the cursor is up here at the top. Now, I've got my fingers on home row. So which one do you think is faster? Do you think moving my hand down to the track pad, and moving down to the fir tree and placing the cursor there, is faster? Or this? Oh, sadly, I hit the first fir tree first — so what I did was Control-S and I typed "fir," and it took me to the first fir tree, but also highlighted the second one. So one more click and I'm there.

So if I want to go to this location right here, 543, then I'm there — I just type out the part of the buffer that I want to go to, and my cursor winds up there, and then I can just leave it there. What I've found is that, on average, not having to move my hand back and forth to the track pad or the mouse — and not having to fumble around to find where the mouse cursor is on the screen (you may have lost track of it, it's off in the corner, so you have to wiggle it a little bit) — whereas you always know where your text cursor is, because you're using it for navigation. So if I want to go to this snow C, I just type "snow C" and boom, I'm there. That's how fast it was. Now, of course it does require you to be able to type. But I've told you again and again: if you don't know how to type, then you're not as good a programmer as you should be. So go learn how to type.

I even wrote — I wonder if it'll even run — a typing test. It's probably not installed on this machine. I have a typing test that I wrote somewhere that actually keeps track of my error rate and my typing and all that. I'll show that another day.

The other thing I wanted to show — there were two things. One is: hey, look at all these files. What if I want to take all the ones that have "cloth" in them, and I want to reverse the order of "cloth" and the second word? So these four files right here, I'm going to rename them all — instead of cloth-air.arch, I want to rename it to air-cloth.arch, let's just say. Let's say I've potentially got hundreds of these things. Well, what you can do in dired, this directory editor, is you can say percent-R, which means rename from a regular expression. And I can say cloth-whatever — capture the next bit, and then end with .arch; so that's my match — and I'm going to replace it with the match group, cloth.arch. And now it's going to say: do you want to rename cloth-air to air-cloth? And I go, yeah, bang. And it just renamed all four of them. You see that?

And they're renamed on disk. If I go to the armor directory in a shell, say, and ls star-cloth — there they are, they've all been renamed. So that's the first thing: being able to rename files by regular expression. I've never seen that functionality anywhere else. And if it didn't exist in Emacs, you could really easily write that function — it would take you probably two or three hours of writing Lisp, and maybe writing a little test for it if you want. But realistically, we don't usually write tests for Emacs Lisp code that's not going to be distributed to other people. If it's your own, just little personal functions.

The other thing I want to show you is macros. So let's say I want to go into every one of these XML files and change something. Here's an idea: what if I need to insert one extra XML line at the end of every single file, right before the closing arch tag right here? That's something that's a little bit harder to do with a script. You can do it, but it's like with a sed script — it's a little tricky. But you can do it in Emacs really easily.

I go to the first file and I do it by hand. So I'm going to start recording a keyboard macro — this is the last thing we'll do today. I'm going to hit Control-X open-paren. It says "defining keyboard macro." And now I'm going to open that file, search for the end, go to the end, back up one line, insert a line, insert two spaces, and then I'm going to say foo tag equals bar. And now I've got the tag. I'm going to save it, close it, and move to the next file. And now I end the keyboard macro. Look — I just recorded the keystrokes that I did, and I chose the keystrokes in a way that they were sort of independent of the length of the file. So now, if you open up gray dragon mail, it does not have "foo tag equals bar" at the bottom. But if I hit Meta-J — which I bound to call-last-kbd-macro — and go back and open it up, hey, there it is.

So now I can do this macro on all my files. And all of them now have that foo tag at the bottom. If I open this red dragon mail — there it is, foo tag equals bar. You see? So it's really, really powerful to be able to record keyboard macros. And the programming model is actually sort of modeled on making the cursor go and do things, as if you were typing it with your fingers. That's how Emacs's programming model is. You can build higher-level APIs on top, of course, but the basic model is: move the cursor somewhere, and then take a look at where you're at and start doing some editing operations.

So this was a quick tour of Emacs. I hope that you enjoyed it. As you can see, I use shells for everything — I have tons of them. I have my own custom modes and my own custom workflows. You can open binary files. You can teach Emacs about new kinds of files that it doesn't know about, by writing special modes for them — and so everybody always does. If you go to the EmacsWiki, you're always going to find modes that people have written for almost anything on earth: any programming language, any markup language, any binary file that's in common use. If there's something useful to be done, like play audio or open an image, Emacs either has it built in, or you can write that mode yourself.

And because it's a continuous start-small — define a variable, define a little function, and it works its way up from there — it's much, much easier to learn how to do plugins in Emacs than it is for a big IDE like IntelliJ, where you have to have a manifest and all this stuff just to do hello world. So it's a super-powerful model. I hope this has been convincing. I know I've failed to show you a whole bunch of things that I do on a regular basis, but this is Emacs. And this is why I swear by it — because a lot of these things, a lot of these personal automations, you just can't do realistically with anything else. There's nothing else on earth that works exactly like Emacs.

Because what it really is, is a command shell — or more like a command orchestrator, a process orchestrator. It can be sort of anything that follows the Unix model of having text I/O, or it can even do binary operations and work on binary files. And hey, you never have to wait for somebody else to write the tool for you. You're not sitting around going, "Man, I wish my IDE could do X, Y, Z," and doing it is a huge bundle of work. With Emacs, you write it in an afternoon, or an hour, or five minutes, or however long it takes you — and you've got that function around forever. Emacs basically never deprecates any APIs. So I've got code that I wrote 20 years ago, 25 years ago, that I'm still using today. And folks, that is an investment that's worth it.

So there you go. If you put a little bit of investment in every single day — or just four days a week — into learning Emacs: learning the key bindings and what all its capabilities are, and learning its buffer model, and how to get help, and how to find packages, and how to install things, and get your color themes and your key bindings all set up the way you like them. If you like vi, use one of the vi emulation modes — they're supposed to be fantastic. Or don't — just raw-dog it and learn Emacs. And then gradually start writing yourself some functions, and learn a little of the Lisp. There are tons of resources; I have tons of Lisp books on my shelf. Emacs Lisp is very similar to Common Lisp, so that's the Lisp you'll probably want to read about — go get a book on Common Lisp, there are tons of good ones. And you're off to the races. You'll be using it for the rest of your life.

Emacs is going to long outlive me. Emacs almost predates me — I think Emacs was invented in the seventies, and I was born around then, and I swear Emacs is going to live at least a hundred years longer than I do. So look, it's not going to be wasted time. It's going to be time well spent.

All right, folks. Well, there you have it — that's my quick little tour of Emacs. I hope you liked it, and I'll see you next week, for Stevey's Tech Talk.

← Stevey's Tech Talk