Tactile: A Structural Emacs Lisp Mode


Of all the fea­tures usu­ally attributed to Lisp, by far the most dis­tin­guish­ing is it’s unique sort of homoiconicity. The lan­guage itself is rep­re­sented in the same syn­tax as its chief datas­truc­ture (the singly linked list,) and is in fact parsed into that datas­truc­ture for pre-process­ing before it is actu­ally com­piled or interpreted.1 This fea­ture allows Lisp code to be manip­u­lated pro­gram­mat­i­cally far more eas­ily than most pro­gram­ming lan­guages. Usu­al­ly, this is used to extend the lan­guage through Lisp macros, but I won­der why it isn’t more often used to enable bet­ter edi­tors and IDEs.

To give you an exam­ple of what I mean, take your typ­i­cal IDE for a typ­i­cal lan­guage, like Eclipse for Java. Among other things, Eclipse has an elab­o­rate Java code parser which it uses to per­form com­plex refac­tor­ing oper­a­tions, such as renam­ing vari­ables, func­tions, etc, or intel­li­gently mov­ing code around. Most Lisp edi­tors lack these fea­tures. Peo­ple who write Lisp code will often say that Lisp has less need of auto­mated refac­tor­ing tools than Java, which is true, but is also sil­ly, because refac­tor­ing tools for Lisp should be really easy to write. The hard part of writ­ing a syn­tax parser is triv­i­al­ized by Lisp’s syn­tax.

That’s just one exam­ple. Other things that Lisp syn­tax should enable in edi­tors are true struc­tural edit­ing, where the edi­tor can treat the code as a tree struc­ture rather than a stream of char­ac­ters, obvi­at­ing syn­tax errors alto­geth­er. Sta­tic code analy­sis, look­ing for obvi­ous bugs, logic flaws, or inef­fi­cien­cies is anoth­er. On the fly regres­sion test­ing, code com­ple­tion/­gen­er­a­tion, bet­ter visu­al­iza­tions, code fold­ing, etc all could be pos­si­ble with a good edi­tor/IDE, and much more eas­ily with a Lisp than another kind of language.2

Any­way, I thought a lot of this stuff would be cool, so I’ve started a bit of an exper­i­ment. Tactile is a mostly true struc­tural Emacs Lisp code edi­tor (in Emacs, of course.) Now Emacs already has a num­ber of fea­tures to allow struc­tural edit­ing of Lisps, includ­ing it’s built in s-exp nav­i­ga­tion com­mands, and the paredit library which not only keeps paren­the­ses (and other paired syn­tax fea­tures, like brack­ets) bal­anced, but pro­vides com­mands which make eas­ier to edit s-ex­pres­sions. None of this how­ever gets quite to where I want to go. Tactile, con­trari­wise, parses Lisp code and keeps actual track of the struc­ture of the buffer. It knows where forms begin and end and can oper­ate on code by atom or by form rather than by line, which is an improve­ment. The end goal is to cre­ate an edi­tor which main­tains per­fect struc­tural integrity in the code. That is, not only will it auto-bal­ance paren­the­ses, it will make it impos­si­ble to unbal­ance them, or to break a string, and it will auto pretty print your code as you type, hope­fully unobtrusively.3 Fur­ther­more, it will auto-­com­plete, refac­tor, auto-­gen­er­ate, and (even­tu­al­ly) sta­t­i­cally ana­lyze code. It should be pretty cool.

For now how­ev­er, Tactile is still exper­i­men­tal, and does­n’t include most of the hoped for fea­tures. It’s pos­si­bly a step up from stan­dard Emac­s+­Pared­it, in that it selects it’s active mem­ber and oper­ates on it in a more ‘tac­tile’ fashion,4 but it does­n’t do much more than that, yet. Also, it only cur­rently works with Emacs Lisp; my ulti­mate goes is for it to sup­port mul­ti­ple Lisp gram­mars, so Com­mon Lisp, Scheme, and Clo­jure would all work to, but Emacs is sim­pler and more avail­able. It does­n’t inter­act well with Viper-­Mode. Also, it’s new, so it may be bug­gy. Despite all this, I’m still hope­ful that this will turn into some­thing use­ful, so I’m shar­ing ear­ly. The ReadMe is in the code repos­i­to­ry, so if you want to try it, go ahead and download it and give it a shot.

  1. Lisps of all sorts can come in compiled or interpreted variations. 
  2. Actually, with Lisp, you generally also have the advantage of a running instance of the program you’re developing, so static analysis can usually give way to simply interacting with the Lisp instance. Structural understanding of the language still helps though because it let’s you map the feedback from the instance to certain forms in the code. 
  3. :D 
  4. Hence the name. 

Last update: 13/09/2013

blog comments powered by Disqus