Text Editor Shenanigans

Ever since I got over the initial learning curve of Vim, I've been one of those loonies who volunteers opinions about text editors. Mostly friends, sometimes family. Generally strangers via the internet. If you've read internet message boards or blogs that relate to programming or software-creation-related disciplines, or sites like stackoverflow, you've likely encountered someone like me.

For instance, I already have at least one post on this blog about text editors, and lo, here is another. Clearly, I have a problem.

Setting all that aside for a moment, this post isn't about what makes Spacemacs so great, but instead it's about how I finally went off the deep end and started writing a text editor of my own.

It started innocently enough. I had the idea to make a Chrome app which does text editing. This was right on the heels of a project at work which used HTML5's canvas element extensively, and I'd been learning about WebGL on the side, so canvas was on my mind, and I decided to render my text editor inside a canvas element. For now, I've concentrated effort on doing it as a web page. Porting to a Chrome app adds some native features (e.g. save files to disk) but if it works well on the web it ought to be even better as a Chrome app.

Step 1 is to just draw something - anything at all - to the screen: owl-approves.png

Step 2 is to actually draw text. Here I'm using canvas' strokeText() method: hello-canvas.png

But this is still essentially just rendering a still image, much like drawing a rectangle. To be interesting (indeed, to even be an editor), it has to be interactive. So we come to step 3, listening to keyboard events from the DOM: comma.png

My strategy so far is to do the minimum amount of code necessary to accomplish each goal, where the goals have been defined like "draw a character on the screen". My hope is that this strategy will give the benefits of maxims like YAGNI (you ain't gonna need it) while keeping the reward part of my brain stimulated enough to propel me through the next challenge.

I do have some plan in mind though, and it goes like this:

  1. implement vim's insert mode
  2. implement vim's normal mode
  3. implement a mode for moving among modes, in the style of Spacemacs

So far this plan is in phase 1, but it's forced me already to:

  • choose a data structure to hold the text (currently a plain array of characters)
  • animate a cursor separately from the text (it can be moved using the arrow keys)

As the app accumulates features I expect some decisions will need to be rewritten, but my strategy of building as little as possible helps with this, because it makes ripping out old code less painful (because there's less of it).

The code is here.

Stay tuned for more updates, but in the meantime, here is a link dump for writing text editors: