Fork me on GitHub

Introducing Ymacs

Ymacs is an Emacs-like editor that works in your browser. Currently (starting with tag v0.4 in the code repository) it works in recent versions of Firefox (and other Gecko-based browsers), Google Chrome and Apple Safari.

This project is based on DynarchLIB, my AJAX toolkit.


How much Emacs-like?

Of course, Emacs is a gigantic beast with some 30 years of history. I'm not ambitious enough I don't have enough time to copy all it's features, but however Ymacs currently can do the following (and I think it's worth its name):

Of course, these features aren't hard-coded in ways that you can't change. Ymacs is customizable and extensible. For example, if you're not happy with Emacs key bingings, it's fairly trivial to define a different default keymap to mimic, say, Eclipse, or Visual Studio. However I'm not familiar with any of these, so I can only hope that this will be implemented by contributors. Do you want to become one?

How did it start?

Like most cool projects, Ymacs started out of necessity. What's ironic is that after hacking on it for a few days, I almost forgot the purpose I had in mind and kept adding features to make it more Emacs-like, faster and more stable and currently, it still doesn't have the features that I wanted in the first place. (however, it got close: it should be easy now to add a decent Lisp-mode).

It started because one day I wanted to learn Common Lisp. I've read some materials, done some trivial applications to see how it's like, and next I thought "OK, let's do websites with it". So I started building a pretty simple content management system, with an AJAX interface based on DynarchLIB. Things were progressing nicely, albeit rather slowly. I implemented my database with PostgreSQL and cl-perec, after serious hassling to learn how to use the latter (which is almost completely undocumented), then I discovered Hunchentoot which is a fine Web server written in Common Lisp, and cl-who from the same author as Hunchentoot (BTW, this guy is fantastic!). CL-Who is a cool way to write XML (thus HTML) directly in Lisp. You could call it a template engine, but it's really Lisp and gets compiled into machine code (depending on the Lisp implementation), which is nice because the templates run blazing fast.

In my CMS I was using an "WYSIWYG" widget for editing pages, which is pretty cool. But each page has one cl-who template. Initially I thought that the templates would reside on the server and would not be editable through the AJAX interface, but then I thought “whY not?”.

So I quickly hacked a new table into the database to hold the templates, and threw together a simple editor for them which was using a TEXTAREA. When I first tried it, I realized that writing Lisp in a textarea is not just unbearable, it's downright impossible. You have to count all those parens. You have to look until your eyes hurt to find out if a string is properly closed or not. There's no editing commands, etc. I'm not blaming the textarea—it wasn't designed for this—I'm just saying that no no, you can't write code into it.

Similar projects - CodeMirror

So I looked for alternatives. There are a few in-browser source code editors (one even claims to be Emacs-like, but that seems to be a joke). The one that worths mentioning is CodeMirror, a project that claims "in-browser code editing made almost bearable". It does stand to it—it works pretty well, it's fast enough, it has very good syntax highlighting and automatic indentation for a few languages. When I checked the author (Marijn Haverbeke) I found that he is a Lisp programmer who actually built some stuff that my CMS prototype indirectly relies on, how cool is that? :-) (Postmodern, a nice library for accessing PostgreSQL databases from Lisp.)

CodeMirror is based on designMode; you should read Marijn's story about writing CodeMirror to see the struggles that the man went through in order to build his editor on top of this interface (by the way, this is a good time to give proper credit: his story inspired me on handling syntax highlighting and indentation using a resumable parser that saves its state at the end of each line).

So, first I thouhgt about using CodeMirror. But I really wanted Emacs keybindings. I have some experience with designMode and I know that it's extremely difficult to figure out where the caret is, for example—which would be necessary to implement movement by word, transposition commands or upcase/downcase/capitalize. It seemed crazy so I rejected the idea to modify CodeMirror. Besides, where's the fun if I'm not doing it myself? :-)

How do you do it without designMode and without textarea? Well, draw your own text, draw your own cursor, intercept all keypress events and figure out what to do with them. That's what Ymacs does.

You can read more about the architecture if you're interested.