Hi everyone!
I'd like to introduce the Aulx project.
An example of a running instance is at <
http://espadrine.github.com/aulx/>,
the source code is at <
https://github.com/espadrine/aulx>.
The purpose is to give any editor advanced autocompletion capabilities,
for the languages of the Web: JS, CSS are available right now,
HTML is coming.
It is very easy to plug into an editor, and has advanced features
(more about this below).
The idea is to reuse the autocompletion system so as to have, for instance,
autocompletion of JS and CSS inside HTML.
Also, quite intuitively, each autocompletion for a language actually
shares a bit of code.
Let me start by comparing my system to competitors.
I started off this journey by looking at the system in use in Orion and Scripted,
but was put off because it is difficult to reuse outside of the Orion project.
Furthermore, it relies on a fork of Esprima which has very unpredictable
(and usually poor) performance. That fork attempts to obtain an
abstract syntax tree
even when the source code is not valid JS.
DoctorJS attempts to do the closest thing to a full type analysis,
next to actually
running the code (which I believe inspired SpiderMonkey's own type
inference algorithm).
It heavily relies on Narcissus, a JS interpreter whose parser is not
acclaimed for its speed.
It doesn't matter for that project, because the analysis itself is
quite expensive.
As a result, it fits better as a one-off ctags than a constantly
updated autocompletion.
Also, it only performs a static type analysis.
It may be defunct, but I still use it when coding in vim; I even
contributed to it to make
the jsctag command work.
Unlike those, I took speed very seriously. The AST walker isn't a set
of recursive functions,
it is a (surprisingly small) while loop.
The static analysis doesn't attempt to do a thorough type analysis.
It relies on property usage (if a variable A is used with a property
B, B will show up
as a candidate) and the result of functions (if a variable A is set to
the result of calling B,
eg, `A = B()` or `A = new B()` even, then all variables set to the
result of B() will have
the same candidate properties).
It may seem simple until you compare working on the full jQuery
source with Aulx
and with Orion. Orion is both slower and less precise.
The only completion for `jQuery.` that Orion's autocompletion gives is the
alphabetically (or rather, ASCII-betically) ordered list of the
properties on Array.prototype.
That's the type that was inferred.
Aulx gives you the full list of properties you might want, including
'fx', 'Event', 'ready', 'Animation'
and so on.
The belief behind the type analysis that I do is that the user wants
autocompletion
to help him explore the source code, rather than just give him type information.
Remember that Aulx is still being worked on to provide more subtle information,
but what it has is already great.
But the project is slightly more than just a static analysis tool.
For starters, it only needs the source code and a {line:, ch:} caret
to get started.
Knowing what type of completion is needed doesn't even rely on parsing the file.
That part of the system, which I call the contextualizer, has a fancy,
proven (for ES5),
algorithm which is both very fast and very resilient.
At its heart is Esprima's tokenizer.
It also includes no-side-effects dynamic analysis, given a JS environment.
I would love to see this feature combined with live development
(and V8's live edit features).
It doesn't stop with JS, too: CSS is there and improving
(I've already started to work on CSS static analysis), HTML will come,
and I hope to have optional languages, too, like CoffeeScript.
I am exploring ideas with the weighting system, too.
Right now, the heuristics are a simple combination of the following
two criteria:
- A candidate that is frequently used is heavier,
- A candidate that is used close to the caret is heavier.
A heavier candidate appears first. It yields subjectively good results so far.
I still have ideas to make it better and more dynamic, too.
This system is likely to make it into Firefox' DevTools,
and I'd love to see it used in other places.
Thanks a lot for reading this!
I'd love to have feedback.
Cheers!
Thaddée Tyl.