Emacs Chat: Christopher Wellons (FFI, Emacs internals)
Christopher Wellons (nullprogram.com, github.com/skeeto/) started using Emacs nine years ago and has built all sorts of nifty customizations since, including something that plays Tetris for you. He demonstrates the benefits of having an HTTP server running inside Emacs by using Skewer to interact with a web browser and Impatient-mode to share his syntax-highlighted buffer through the Web. In addition, he covers foreign function interfaces, packages, and other good things.
- https://github.com/skeeto/impatient-mode
- https://github.com/skeeto/.emacs.d
- https://github.com/skeeto/autotetris-mode
- https://github.com/skeeto/emacsql
- https://github.com/skeeto/elisp-ffi
The recording and transcript for this video are in the public domain.
Audio and Video
Transcript
Sacha: Hello and welcome to another episode of Emacs chat. This time with Christopher Wellons, who is, among other things, the author of something that will play Tetris in Emacs for you. Hello, Christopher, thank you for joining us.
Christopher: Hello.
Sacha: I initially reached out to you because I read your blog post about foreign function interfaces and all those other things. Then I realized you are the same guy who put together skewer-mode and other really, really cool interactive ways to use Emacs. But before we dig into how you got into Emacs and all the interesting things you do with it, can you tell us a little about who you are outside of Emacs?
Christopher: I'm your typical computer geek. I've been using Emacs for 9 years. I run regularly, I'm out there 3 days a week. I like computer games. I like reading. I spend a lot time watching YouTube videos, actually. That's a big hobby. I find these long, half-an-hour long clips, mostly people playing video games. So instead of playing games myself, I watch people play games. A lot of time I can do my own thing while doing that, so it's almost like multitasking that way.
Sacha: You get all the benefits of the funny moments of the games without having to do any of the hard work. I noticed on your blog that you also make computer games? Like roguelikes?
Christopher: Occasionally. I like participating in the Seven Day Roguelike (7DRL) contest every year. That's a fun thing to do for a week. I like the constraints, but I only do it for about a week, then I get to forget about it after that.
Sacha: You mentioned you started Emacs 9 years ago, which is pretty amazing. How did you get into it?
Christopher: So I was on an internship in college, and I was getting a lot more serious about programming. I've been programming for 19 years now. When doing the internship I was getting serious about it. Up until that point, I'd just been using KWrite and some other, some basic stuff.
2:30
Christopher: I read probably something by Richard Stallman, or Steve Yegge, some of his Lisp essays. I decided I should look into this Emacs thing, and that's what ended up happening. I installed it and read the manual. I got one of those O'Reilly Emacs books. I read that, then just gradually built up from that point. It became my only text editor quickly.
Sacha: Were you customizing it right away, or did you start off using it as a programming environment for a while?
Christopher: I was customizing it right away, mostly copying and pasting snippets here and there, because I didn't understand what a lot of it did. For example, this thing will tell me how many words are in a buffer, and I dropped that into my configuration.
It wasn't until actually a few years ago that I started. I put my Emacs config in source control. So the whole thing is carefully curated now, unlike the mess of files I copied around for a few years there.
Sacha: So did you end up declaring Emacs bankruptcy then and starting from scratch when you started curating your config?
Christopher: It's pretty close to from scratch. It got heavily redone. I got a little macro to help me organize things and package things up in a nice clean blocks. That happened at the same time I got source control, almost like a rewrite.
Sacha: 9 years ago, we didn't have a lot of the same resources we have now about for learning more about Emacs configuration. No Github … I don't remember if EmacsWiki was around then. So you mentioned the book was useful–the O'Reilly book. What are other resources you found helpful?
Christopher: I gave away the O'Reilly book years ago, because that's just a beginner book. I gave it to a coworker hoping to get her into Emacs. But since then it's really just been primarily reading the Emacs Lisp Reference Manual. There's still so much in that manual I don't know about. I go through it all the time and I've gone through it cover to cover a couple of times. There's still things I miss, little details, and I go back like, "Oh, I didn't know you could do this."
Sacha: Yeah, I find that every time I read the manuals, I came across something new. Last time I reread the Emacs manual, I learned how to add Unicode characters. There's just so much to learn. Definitely reading the manual, and probably reading the source code as well.
You mentioned a coworker. You have other coworkers who are actually using Emacs too?
5:26
Christopher: Yes, I've got a few coworkers. Not many. I spend time discussing Emacs with all of them on occasion, kind of sharing notes on how we do things. What's funny is pretty much all of them have adopted the color theme–I went with the "wombat" color theme that comes with Emacs–and it seems everybody is using that now. That's kind of fun to see that. "That looks familiar," when I see their screens.
Sacha: Yes it's interesting to see the diffusion of practices when several people who use Emacs work together. Your config is on Github so I guess people can pick up interesting tips off that one as well.
So you check with other people, learn from books, learn from source code. All the hacking you've been doing about building web servers and other interactive servers… You actually even put together something that can talk to inferior Emacs processes? Or running Emacs within Emacs, or something of the sort?
Christopher: That was a project a couple weeks ago. I didn't even announce it yet at this point.
Sacha: How do you get to the point where you are comfortable enough with Emacs internals to just say, "Oh, I think I would like Emacs to live with a web browser?"
Christopher: That's basically what it comes to. I can make it do almost anything I want it to do right now. If I have an idea, I'm going to try that, and that becomes my primary focus for a short period of time until I make it work.
To elaborate on that… I got a Steam account. I've got something like 200, 300 games in there, but I rarely ever play them, because these little programming activities are almost always more fun. Like, I can play this game, or I can tinker with Emacs. It's almost always Emacs. Tinkering with Emacs sounds like more fun.
Sacha: Emacs is more addictive than games you can play on Steam. I've heard that from other Emacs users as well. This is what we do for relaxation and fun and intellectual curiosity. So basically you learned about all these things by having crazy ideas. Like: "What if I can use Emacs to play Tetris on its own?", and then digging around and figuring out how to do it.
Christopher: So you saw the autotetris-mode then?
( autotetris-mode https://github.com/skeeto/autotetris-mode )
Sacha: I just came across that today. I often show Tetris when you are demonstrating Emacs to other people and you want to boggle their mind about just how much is in Emacs. So I normally show things like Tetris and doctor. Now I can show Tetris and Autotetris, and drive people crazy. Lots of really odd and interesting things.
One of the things that people are often curious about is how actually people use Emacs. What's your workflow like? What are the different things you've configured? You've shared your config on Github. ( https://github.com/skeeto ), but we'd like to see the highlights of your config–particularly interesting snippets that you like using.
Christopher: Sure. Should I switch to my screencast here then?
Sacha: And folks, you can ask questions by submitting to the Q & A app or adding them to the event page. Or if you are on IRC, there's emacs-chat channel on Freenode.
Christopher: So here is my init file. Something that will stand out
pretty quick: I've got this with-package
macro here. You'll see that
show up over and over again. This is something I wrote myself. There
are a bunch of different versions. Everybody's written their own
little version of this because there isn't an official one at this
point. It groups related configurations options together into a block.
So instead of having all this loose stuff just dumped in, I
can say, "Everything related to uniquify
goes in this block,
everything related to eshell
is going to go in this block right here."
Christopher: I don't have to list any of the packages explicitly. So
I use ELPA and MELPA. If I just mention it here in this
with-package
, it will automatically get installed when Emacs starts
if it's not already installed.
Sacha: Hmm, I should use that. I've been using use-package
by
John Wiegley ( https://github.com/jwiegley ) but it doesn't do the
installs.
Christopher: I think use-package
is another one of these macros
that somebody else has written. There are a few of them out there.
Mine's kind of cryptic. If you look at this entry here, I got this
asterisk. So the ones without the asterisk are lazily loaded. They let
Emacs load them with autoload as late as possible. Those with asterisk
are force-loaded. Like uniquify - I don't want to wait for something to
happen for that to load, I want it just load right away, so that it's
active. So it's got an asterisk on it. Same way with winner-mode
.
With winner-mode
, you can hop up with arrow keys back and forth
between buffers. I like doing that.
Then there are asterisks on other things that have to do with
auto-load
. It's pretty cryptic, but it's really useful for me. That
why I haven't put this out there for other people to use.
Sacha: Sometimes you have asterisks after the package names?
Christopher: Yeah, that's something changed with package.el
, in
the latest changes. It used to create a secondary package with the
same name but -autoloads
. There's this really cool trick where
you could require
the autoloads package and you can do some
configuration lazily. There's a nice trick, but they got rid of that.
There's no longer this autoloads package that's generated, so I had to
modify my with-package
macro. So it has the same effect, and to do
that, I have the asterisk on the package names when I want that effect.
12:41
Christopher: In this case, I want it to make sure I load the
autoloads of the markdown-mode
– something like that – so when any
of these patterns are opened, it will get set in markdown-mode
,
because the autoloads has already been set. It's something like that.
I can't remember the details right now.
13:11
Other than that, there's not too much special in here. Just a bunch of
things that I like to use. Like right here, I can quickly lookup Java
documentation. I got that down to C-h j
. So normally you can lookup
documentation with C-h f
so I can lookup Emacs stuff. Let's say I
want to look up ArrayList
. It'll pop up a browser over here.
These are all the packages that's been loaded in this quick jump stuff. What makes this really work well is that Java's Javadoc is ubiquitous. All these packages have Javadoc packeges made, so documentation is in this nice clean format that I can jump to anywhere. I can jump into Lombok documentation that's installed locally on my machine by this process.
Sacha: Yeah that's good stuff. I often find myself Googling for all these details, but it's nice to have that just a quick keyboard shortcut away.
Sacha: multiple-cursors
is one of those things I hear it's super
awesome, but I haven't got my mind around it yet.
Christopher: Yeah it lets me do this, and modify the stuff I want. I
love that. I used to do stuff like that with a macro, but
multiple-cursors
, that's so much more comfortable.
Sacha: That's awesome.
Christopher: Something I did want to show was impatient-mode
since
that was asked about specifically. So if you visit in your web browser:
( Impatient Mode. See your Emacs buffer in a webpage as you type: https://github.com/netguy204/imp.el http://nullprogram.com/blog/2012/08/20/ )
Christopher: You'll see if you click on the scratch buffer, you'll see a copy of my scratch buffer here. And it has syntax highlighting in a web browser.
Sacha: That's awesome! How will you use this?
Christopher: If I need to share my screen with somebody remotely,
this is easier than going through a normal kind of screen sharing
session like right this minute. I can just turn on impatient-mode
,
and then give that URL, and they can visit that from a browser and
watch what I'm doing.
Its really useful if I pop up an eshell
like this. I can run a shell
here and share that too. Now if I turn on impatient-mode
like this,
now you be able to see this buffer too.
Sacha: Are you building any 2-way communication into this at some point?
Christopher: Nope, it's just one-way. And this is actually a collaboration between me and Brian Taylor. He's a coworker and a friend of mine.
( Brian Taylor's blog on impatient mode http://www.50ply.com/blog/2012/08/13/introducing-impatient-mode/ )
It's built on the same web server, which I call simple-httpd
. it's
the same one Skewer uses.
( skewer-mode https://github.com/skeeto/skewer-mode Skewer: live web development with Emacs Provides live interaction with JavaScript, CSS, and HTML in a web browser. )
( simple-httpd https://github.com/skeeto/emacs-web-server )
Any time I'm doing something with Emacs that involves the web, it's using my little web server.
Sacha: I should try that too. It looks like you've put it to all sorts of really good uses. You already have a video demoing Skewer which allows you to easily interact with the JavaScript in a browser. I think it's pretty darn cool too.
So there's impatient-mode
and Skewer. So FFI, foreign functions, how
are you using that? I saw your blog post demonstrating it, but am
curious about the practical applications that you were exploring.
( Emacs Lisp Foreign Function Interface https://github.com/skeeto/elisp-ffi )
Christopher: That kind of hit the wall a little bit, as it gets complicated pretty quickly. I don't have any real practical uses for it yet, I thought maybe I can run a GTK window, and run a little graphical system that way. But as anybody who uses Linux and has launched GTK applications from a terminal knows that they're really noisy. They spit out a lot debugging messages. I haven't made it robust enough. Those messages actually interfere with my communication with Emacs. As it goes into pseudo-terminal and error messages and standard messages get piped into the same pipe, and because of that it gets in the way. I haven't done anything significant with that beyond just a little demo, which I can show here really quick.
18:45
So I'm just going to copy right out of my README here and drop them
here. So, whenever you start using the FFI, it has to create what I
call a context, which is really just an inferior Emacs process that's
running my little FFI program. It's really simple. It's a stack machine
that I can send strings and basic values to, so I can… Say I've got
srand
, so here's my function name, here's the function signature,
and it can push all these values into the stack, and pop the values
off and I get them in Emacs.
So here I can seed. If you know the C function srand
, it seeds the
random number generator. It returns a void. And I can start generating
random numbers.
Sacha: You said it's an inferior Emacs process?
Christopher: It's an inferior process. If I hop into here … you see this glue program? So it's just a C++ program that's linked with libffi right here. And it just drives libffi through this really simple protocol that it chats with through a pseudo-terminal, through a pipe I am using.
It's just a pretty simple stack machine that makes it work. There's the switch for the "byte code", and I can push different sizes of integers onto the stack. And that created this little glue program right here, "ffi-glue." So that's what runs in the background.
Sacha: You mentioned you managed to get that to work as a package and I was curious about how it all came together.
21:01
Christopher: If it's going to be a package, there's complications such as how do you handle that binary. That's something I resolved with EmacSQL.
(EmacSQL http://https://github.com/skeeto/emacsql EmacSQL is a high-level Emacs Lisp front-end for SQLite (primarily), PostgreSQL, MySQL, and potentially other SQL databases.)
So that runs a sub-process in the background. In order to make that work with SQLite out of the box as a package on MELPA, it ships with C source code. It will attempt as best as it can to compile that when you install it, so it might take a minute to install because its going to run a C compiler synchronously to get that to work. I can try to demonstrate it.
I'm going to make a SQLite database. This is a connection object. This is using a really cool part of Emacs–it came from CEDET–called EIEIO, which I think is really clever.
( EIEIO http://cedet.sourceforge.net/eieio.shtml EIEIO is an Emacs lisp program which implements a controlled object-oriented programming methodology following the CLOS standard)
It's an object system a lot like Common Lisp's CLOS.
So these functions, there's also [interface for] MYSQL and also PostgreSQL one, actually 2 PostgreSQL drivers, I can do this, this is the database name, called "testing."
It'll create this database object. Thanks to EIEIO, it'll work with all of them the same, because they are generic functions. It'll work with the same functions. So once you have this database object, you don't care what's there anymore, you can just use this same EmacSQL function to make queries on it.
I can say create-table
, like this:
(emacsql db [:create-table foo ([name id])])
and I can insert values into it:
(emacsql db [:insert-into foo :values])
Notice this is a s-expression, so instead of doing:
SELECT * FROM foo
I build up these vectors of symbols and it actually compiles into SQL expressions. I can demonstrate that.
So here's a expression:
(emacsql db [:insert-into foo :values ["Chris" 0]])
I can compile that right there.
Output:
INSERT INTO foo VALUES ('"Chris"', 0);
That's what it compiles to.
Then I can make queries on the database.
(emacsql db [:select * :from foo]) (("Chris" 0))
About the extra quoting… I'm not sure I made the right choice on
this. Anything that's not a number. First, nil
maps to NULL
. I can
insert a NULL
into database just by using a nil
there. Anything
not nil
or a number, will get printed into a string, and that whole
value is inserted into the database.
26:00
Sacha: What got you interested in building this in the first place?
Christopher: It goes back to Elfeed, which is my web feed reader.
(Elfeed https://github.com/skeeto/elfeed Elfeed is an extensible web feed reader for Emacs, supporting both Atom and RSS. It requires Emacs 24 and is available for download from MELPA. Elfeed was inspired by notmuch.)
skewer-mode
is probably my most used Emacs package right now. But
the most useful for me has been Elfeed. I created it after Google
Reader shutdown. I wasn't happy with any of the alternatives, so I
thought, I could do better than all these, I'll write my own, that's
what I ended up doing.
So I wrote this in August last year, I wrote EmacSQL around the beginning of this year. Back in August when I wrote Elfeed, I needed a database to store all this stuff in. So if I clear this out, you going to see just the last 10 weeks (of blog feed entries). These are all the different entries I've read and looked at.
In the last 10 weeks, there's been 2,451 entries. These are all stored in the database. You see all these tags, the green on the right… These tags, I can go into these, look at the content inside. Here's an Irreal post that would be likely about Emacs. So I can read them here right inside Emacs.
28:55
Sacha: I saw in your screenshot you have images working in this, too.
Christopher: Oh yeah. There you go. There's one, this is my own blog. So I can read my own posts right here in Emacs and go back and forth between posts here.
That's where EmacSQL comes in. I need a database to store all these info, and efficiently index it. If you look down at the bottom here, I press s. I got this filter. You see this:
Filter: -junk @10-weeks-ago nullproam
I start to type my blog name in, and you see live filtering.
Let's say I want to see everything with the tag +youtube
Filter: -junk @10-weeks-ago +youtube
It shows all YouTube stuff in the last 10 weeks. I can narrow it down to 4 weeks, or 1 day ago.
Sacha: I like that. Really cool stuff.
Christopher: So I need to search this fast, and I end up writing my own database format.
There's no database really suitable for this in Emacs. That's why I struck out to write EmacSQL to try to provide a database, so it'll never have to be done again.
I started to port Elfeed to EmacSQL. It's not finished yet. I'm not sure I really want to do that or not, but that's something possible in the future.
Sacha: So it sounds like you spend fair bit of your life inside Emacs. You read blogs, web browsers, and other things… what else do you do inside Emacs?
Christopher: So I do email too. I prefer Notmuch as my email client.
( Notmuch http://notmuchmail.org/ )
Sacha: I heard good things about it. What do you like about it?
Christopher: You notice it looks pretty similar to Elfeed. We've got tags on the right. It actually inspired the interface for Elfeed. I like how fast the searching is, how quickly everything works. It's really nice to use. It goes back to 2005.
Sacha: I'm going to give it a try. I've been using Gnus, but notmuch sounds very interesting.
Christopher: I did try mu4e. I tried it and it wasn't as nice as Notmuch. I didn't like it as much as Notmuch.
Sacha: So you use mail… Your config mentioned you use Calc. Do you use it just as a calculator or do you have any other fancy things for it?
Christopher: Pretty much as a arbitrary precision calculator. As you can see, I already have something in there that it was computing. A lot of times… I just like… Like "What's 2128?" I just like being able to do that any time I want, without worrying about precision. It's useful to be able to do these quick calculations. I always have Emacs up anyway, so I can jump to that.
And if I need to do units, it'll keep track of units for me. S for seconds, change it to year. This is really handy.
Sacha: That's great. I just have to get the hang of all these things. Calc is great, it's like a microcosm in Emacs. This absurdly powerful and flexible thing.
Christopher: It can do calculus. It's a full computer algebra system. It's not fair to call it a calculator really, because it's so much more than that.
Sacha: So you write a lot of Markdown, I'm guessing from your config?
Christopher: Oh yeah. I write my blog in Markdown. All those posts are Markdown. All the READMEs. I just prefer Markdown for all my documentation.
I haven't made the jump to Org Mode yet. It's been this thing I haven't learned. I've never learned enough about it to make good use of it. I know you love Org Mode right?
Sacha: I find it to be similarly flexible. You can do all sort of things with it. But you've got lots of things in Markdown. Basically, that's the way your brain works. I guess Org Mode is similar, but the syntax is different. There's a little bit of friction to get over.
If you're not using Org Mode, are there other ways you manage your tasks?
Christopher: Outside of this, I'm not actually all that organized. I just work from my head lots of the time, more than I should. I forget things, not even knowing I forget them.
Sacha: You manage to write a whole lot of rather-large-looking code, all kept in your head, so… wow.
Christopher: There's something about Elfeed. I noticed you are writing a post about… You logged all your activities. You track how much time you spending on all these various things. I recently came up with Elfeed… On the side of my website, you'll see these lists of places (blogs) that I recommend checking out. This huge list. I was manually maintaining these lists until recently. I realized I can tab the Elfeed database to fill these out for me, since I'm already maintaining all these stuff in Elfeed.
Here's how it worked out. Here's my blogs. Here's where the list come
from, a list of blogs I was recommending. I wrote this function called
jekyll/insert-urls
and I got a little filter string here:
<!-- (jekyll/insert-urls "+blog -product -myself ") -->
So I can just run this. It'll evaluate it right in the buffer.
Oh, it's supposed to be working.
Sacha: That's all rright. It's the nature of all demos, to have something go wrong. I see the idea. Since you already have all the data in your reader anyway, you might as well use the same interface for searching for tags or whatever. You might even consider kind of capturing your reading data, and organizing your list so the stuff you like reading more actually does show up earlier in the list.
Christopher: Yeah. That's something I should probably track more. As I read things or rate them, and somehow capture that info and track them in Elfeed. I got a database right there. I can capture the info and make use of it in the future.
Sacha: Cool. So you do a heck of lots of things in Emacs. Anything you haven't got around to do in Emacs yet?
Christopher: There's a barrier for me to learn new programming languages. This touches on Skewer mode. Before I get into a language, I want to have a workflow set up in Emacs the way I like it. That's how Skewer came about. I need to learn JavaScript and web development, and I need to find some workflow in Emacs to make it work. I looked at swing.js and it didn't quite do what I was looking for. I ended up writing Skewer mode while I learned JavaScript.
Sacha: Let me see if I understand this correctly. You want to learn JavaScript, so you developed something in Emacs that talk interactivity using JavaScript to a browser, ending up writing however many lines of code in JavaScript to communicate with the Emacs process.
Christopher: Yes.
Sacha: In order to learn JavaScript?
Christopher: Yes. It's part of learning. A good exercise too.
Sacha: That's totally awesome. I would've expected that you've been doing this for a while, like years of experience with JavaScript, and you got really tired of the round trip or whatever. So, having this be your first step into this is really cool.
Christopher: I can demo how that works real quick.
I use Pentadactyl, by the way, so I can switch around tabs here. I've
got a vim-like interface to my browser instead of an Emacs interface.
So I say run-skewer
and it opens a blank tab here in a browser
that's connected to Emacs. I pop up a JavaScript scratch buffer. I
got a scratch buffer for every language. I've got a scratch for Emacs Lisp.. If I hit C-J
… C-S
to jump to my scratch buffer. If I want to get to Javascript, I hit C-D
… I don't know why. Something else was conflicting, so I went with C-D
. I can write JavaScript expressions:
Math.pow(13,2.1)
[result shows under the expression]
I've got another… That's my other computer, actually. I was working on something and it's still connected. So I can evaluate values here and put them in a buffer. There's also a REPL.
Sacha: I love the profusion of REPLs you have.
Christopher: Yeah. I love live systems. Steve Yegge has a real well-done essay about live systems, about why they are powerful. I recommend checking that out. You can probably find it on Google pretty quick.
So this is connected to the tab right here. To prove that, I can
switch to my CSS scratch buffer. I want the background
to be red, and I evaluate just like in Emacs lisp. I press C-x C-e
.
Christopher: And I want JavaScript here. I switch to a HTML
buffer… Selector… insert the page. This part is a bit crude. I
haven't got this refined yet. It's got limited use. Say I want to
insert a heading on the page. I can evaluate this <h1>
just as if
it's an expression. You can see it on the screen.
[demo of live change of HTML/CSS]
41:52
Sacha: How do you save it afterward?
Christopher: You can just save the buffer, but that might not be sufficient. There's really no way to capture right now.
You can see that it's just building up CSS style sheets on the page. It's messy. So I'm not sure one would want to capture it as is.
Sacha: It's really good for experimentation. I can see how the live workflow is really great for feedback. Even hitting the refresh after changing the CSS is just a little bit more friction.
Christopher: Yes, I hate that so much. I want to treat web development as a live system I can hack while it is being built.
I can go further with this. So here's my blog again. You see this little green triangle on the top right corner. I can click and toggle that. When it's green, that means Skewer can edit this page. This works not just with my blog. There's a little browser extension I wrote to make it work with Skewer. I can toggle this on any page. For example if I'm on Github… although this won't work with Github website because they've got security cranked up so much. They won't let this work.
I can hook into it, and come over to Emacs and execute JavaScript code on that page, and same for CSS. This way, I can tab into any page and do anything to make it work.
Sacha: I have to go to get that setup, definitely.
I guess you use that for a lot of development?
Christopher: Yes. It's made JavaScript one of my preferred languages to use, actually. There's WebGL now, and you've got HTML5 canvas, and you've got all of HTML. If I need to write a program live that has a graphical interface, I'm like, "Oh, Javascript and HTML." I can hack this up without ever refreshing a page.
Sacha: You mean like the Voronoi toy thing that we're looking at?
Christopher: That's what I was doing before I started…
I got is this cool thing with it. If you are familiar with Voronoi diagram… Each section is everything that's closest to this vertex right here. This is WebGL. The original idea was that I can write a shader for each pixel on the screen. It compares to every vertex and colors itself appropriately. The GPU should be very good at that. I came up with a even better version involving 3-dimensional cones and a depth buffer. That's a lot faster. That's why I got this out. You can actually drag these around, just like this.
It's a little slow on this machine because I'm using plain open source drivers that Debian ships, which is not as fast as on a machine with real video drivers.
It's pretty fast considering it's not doing any sort of exact evaluation of the Voronoi diagram. There's something called Fortune's algorithm that has sweep lines that travels across and doing all this stuff. Tthis is really just a brute force with the graphics card doing most of the work.
It's developed live with Skewer like this. I can change the shaders and update the page while it's running and try things out without doing that refresh stuff.
Sacha: You are working with a lot cool things. One thing I want to mention because it's also really cool too but non-technical–you have released all, practically all of your things into the public domain? What prompted that decision? What got you interested in it, and how's that played out?
Christopher: I started out using GPL about 7 years ago. I read Richard Stallman's Free Software Free Society. I actually have a signed version of that right here. I got really into FSF and got a membership, and everything I did was licensed under GPL.
As I got more experience, I found that licenses are cumbersome. If I want to use even just a snippet of somebody's code, to formally follow the license, I've got to list their names and follow all these rules to make it work. It's cumbersome to worry about licensing licensing stuff all the time, especially if you involve more and more works that have all their own licenses, even if it's just these 3-clause BSD license that just require credit. Even that gets cumbersome. So I decided I didn't want any part of that. I just want to make my code as useful as it can be to most people as possible. I do that by putting it in public domain. Nobody's got any obligation to me when they use this stuff.
Sacha: Thank you for doing that. There's certainly a lot of stuff that people can build on. For example, that web server is probably going to get added to my config shortly after this. It's great that you sharing them so freely.
Do you have any other tips for people who are curious about getting into Emacs internals or playing around with some of these cool stuff?
Christopher: You have Emacs source code. Sometimes not everything is documented clearly in the docstring, so you might have to dig into source code to see how it works, or if you're having bugs, a lot of times you need to dig into the source code to see what's wrong.
I guess the main resources are.. I actually don't read the Emacs
manual much at all. It's kind of a high level user thing and not
really useful for hacking Emacs. The really useful manual is the Emacs
Lisp Reference Manual. It comes with Emacs. You can see in the info
page here. C-h i
. It's called Elisp
at the top level. It covers
everything, or almost everything. You can see how big it is. This
index is 1400 lines, and everything is here. You can just search for
anything in particular. So, like, how do processes work? I can just
search the string processes and read about how it works. There's a lot
of sections and features I'm not aware of and I get surprised all the
time.
So, yeah, use the Emacs Lisp Reference to see what all of Emacs can do
and how you can hack it. Occasionally you have to dig into the source
code of Emacs itself to see how things work. A recent example of that
is, in Elfeed there's a bug, where if somebody wanted to use
x-get-selection
to get the latest clipboard selection… How this
function is defined depends on what platform you are on. The doc
string for x-get-selection
doesn't really elaborate on how the
different platforms vary. What's convenient about this is there's link
to the source code, see this `select.el'? I got a keyboard shortcut
that can jump right into the source code. So you see here's the source
code for x-get-selection
.
Sacha: Sometimes I find myself needing to dig into the C source code as well.
Christopher: Yeah. That's another way I got into the Emacs internals. I've written two lisp interpreters. One of them I wrote myself, which is a crappy toy lisp. Another one is with the Brian Taylor I mentioned before. We wrote a Scheme interpreter together.
I have experience of how Lisp is put together internally, so I can look at Emacs and see lots of similarities, understand what's going on, and navigate my way around.
Sacha: Did you do lisp before coming into Emacs or the other way around?
Christopher: It's hard to say. It might've been that lisp interested me and I got into Emacs initially, but as I said, it was nine years ago I started Emacs. It was both lisp and Emacs that got me into it at the same time, so I can't remember which came first. They kind of came hand-in-hand.
Some people online ask, "How do you get into Common Lisp?" One of the answer is Emacs. That's one of the most powerful editors for Lisp right now.
Sacha: It made sense. Lots of people have built very interesting workflows on top of it. Thanks for sharing your workflow. It looks really cool.
Christopher: Thanks.
Sacha: That certainly gives me lots of things to play around with after this, and I hope a lot of people both listening live and afterwards get to play with this too. Thank you again so much for taking your time to share you workflow.
Another curiosity. I'm doing these Emacs chats as a way for other people to get to how how people use Emacs, how did they get into it, what kind of cool things people are working on. Is there anyone you like to see in one of this episode?
Christopher: If I were to pick a name, I would say Steve Purcell. He's the curator of MELPA right now.
( Steve Purcell's Github https://github.com/purcell/emacs.d )
Sacha: I'll reach out and see if he's interested.
Christopher: That's like a witchhunt sort of name. I give you a name, and you go to them and they give you a name.
Sacha: I find that there's simply no way to keep track of all the cool things that are going on in Emacs. I came across your blog and that's great… I don't even remember. You must be on Planet Emacsen, right?
Christopher: I don't know if it shows up there or not.
Sacha: Maybe I should check. It's a great way to discover other people's blogs, but sometimes there are people who are doing cool stuff who don't show up there. I'm glad we had this chat. If you're listening and you have a cool story or demo, please feel free to reach out. You can find this stuff at http://emacslife.com or at http://sachachua.com - http://emacslife.com is probably easier to spell. Christopher, where's the best place for people to find you?
Christopher: My blog and on Github, I guess, are the two ways. My e-mail address is easy to find. You can just email me. If it's related to one of my packages, you can just open a issue on Github. I try to get to those pretty quick, although I have a few hanging issues that are unresolved right now. I try to get to them fast.
Sacha: Github has been great for discovering interesting Emacs packages, configuration, all sorts of things. Anyway, that's http://nullprogram.com and http://github.com/skeeto .
All right! Thanks, everyone for listening in. I'm going to end the broadcast here. You can find the recording on Google Plus events page. It will also be available on http://emacslife.com/ eventually, once we get the page and transcript and other good things sorted out, and all of that would be in public domain as well.
Check out Emacs Chat for more interviews like this. Got a story to tell about how you learned about or how you use Emacs? Get in touch!