Ruby IntelliSense Libraries - code completion without the code!
From the early days of Ruby In Steel we decided that our IntelliSense would be the ‘real deal’. The plain fact of the matter is that while it’s pretty darn’ easy to add simple ‘code completion’ features to an editor - the kind of thing that pops down lists of methods after a dot or when you press a hotkey such as Ctrl+Space - getting it right is a whole lot harder.
Some editors have ‘code completion’ that just pops up pretty random lists of methods that may be right but, just as often, aren’t. Others use what’s called ‘heuristics’ - that is, sets of rules that try to figure out in advance which methods are likely to be appropriate in specific files or classes. They get it right more often than editors which no rules at all but they still rely on a good deal of guesswork ‘ahead of time’ rather than real-time code analysis.
Ruby in Steel’s IntelliSense doers it the hard way: it actually interprets the code of your program as you write it. It analyses all the required files and all the classes from any libraries you happen to be using. In essence, our IntelliSense engine is a bit like an ‘in memory’ Ruby interpreter.
The advantage of this is that our IntelliSense is as accurate as it is possible to be short of actually running the code. Ah, but there’s the rub. Since it needs to interpret the code itself, it can only provide IntelliSense for fully ‘runnable’ programs. in short, if your code can’t be run by the Ruby interpreter, our IntelliSense engine can’t (or, anyway, couldn’t previously) provide you with code completion.
In some circumstances that’s a problem. For example, almost none of the code files in a Rails application is runnable ‘as is’. Try it. Pick a controller file and try to run it ‘standalone’ in the Ruby interpreter. It will fail horribly - and so did our IntelliSense engine. But not any longer!
With the release of Ruby In Steel 1.3, we’ve added a tool called The IntelliSense Librarian. This let’s you pick sets of Ruby code files - or even entire directories of files - and compile them into Ruby ‘symbol tables’.
These compiled Libraries are then added as ‘references’ which you can see as branches in the Solution Explorer. When symbol table libraries are added like this, the IntelliSense engine can make use of them just as though they were ordinary Ruby source files that had been required in the traditional manner. The end result is that the IntelliSense engine can now interpret whole applications even when the source files containing the classes and methods needed for code completion are missing!
Finally, I think this gives us the best of all worlds. We can now provide IntelliSense from any user-selectable code files even when those files are not available to the code being edited. This means we can provide IntelliSense in previously inaccessible places (that is, we can interpret programs which even the Ruby interpreter itself cannot) without sacrificing accuracy.
Incidentally, even though you can create Libraries for use with any Ruby program, we recognise that most people, most of the time, will want to use this feature with Rails. To make this as simple as possible, we have auto-generated Rails symbol tables in advance and these are made available to any new Rails applications. You only need to use the Librarian to extend the standard Rails libraries - say, to include third party code - or if you want to add database-specific IntelliSense using our new Database Librarian.
I’ll have more to says about Database IntelliSense shortly. In the meantime, bear in mind that the Ruby In Steel 1.3 manual and integrated help have both been updated with documentation on the new IntelliSense features so be sure to read those for further guidance.