Filling out Ruby IntelliSense
We’re just getting ready for the next drop of the current beta of the Developer Edition (’Red Fire’). I’ve spent most of the last two weeks since the first release of the 0.8 beta getting the bugs out of IntelliSense, improving it and making it work smoothly.
One of the problems has been that there are two threads involved in parsing in Visual Studio (nothing to do with Ruby – that’s just the way Visual Studio works). There’s a fast thread which is involved in colorizing the text in the Editor window and a slower ‘background’ thread that handles the parsing. Well, I hadn’t quite got the synchronization between the two correct and so the IntelliSense was a little intermittent. Still, that’s fixed now – and I’ve also added seven more coloring options : you can now color constants, instance variables, method names, class names, etc. You really can get some psychedelic effects.
I’ve also just reached the point where the IntelliSense is ‘functionally complete’. That is, there are no more features to add (at least for our January release). The last three parts were
generating IntelliSense from ::
It’s this last one which is the trickiest. Linking into Visual Studio is relatively easy – there’s good support for IntelliSense ParameterInfo in the Visual Studio SDK. What isn’t so easy is working out what to display. The problem with Ruby is that, unlike C# or Java, there is no way of specifying the class of a parameter. Nor is there any way that the Steel Inference Engine can work out what a parameter is: parameters are by definition in Ruby inputs to a method. Actually, that’s not quite the whole story – but it’s mostly true in Ruby.
So, I decided to add method comment blocks. These tell the Inference Engine what the types of the parameters are. I’ve extended the RDOC syntax a little bit to make this work … look at the code below:
#:return: => Array
#:arg: a1 => String
#:arg: a2 => Fixnum
#:arg: a3 => Hash
# this is the method's description
def x(a1, a2, a3);
This tells the Inference Engine that the method should return an Array and that the class of the first argument is expected to be a String, and so on. This might offend Ruby purists – after all, the whole thing about Ruby is that it’s dynamic! Well, it’s a free country – you don’t have to use it if you don’t want to. We’re not enforcing this; but it’s there if you want it. Personally, I think that the more help you can get to do the job, the better.
People can (and mostly do) write Ruby programs in text editors. Quaint, really. My experience as a project manager taught me that the more productive you can make your team, the more likely you are to get your project in on time and budget. If an IDE can improve the productivity of a humble programmer by just one miserable percent over a small three month project, it’s worth the money.
How it works
As usual in Visual Studio, ParameterInfo is displayed when you hit a ( and this is what we get: Incidentally, this only works if you use brackets in method calls. That’s because something has to trigger the parameter info and the opening bracket is the thing that does this. So this gives you a good incentive to use brackets – not only does it make the code clearer and less ambiguous, it also give you IntelliSense. As I move through the argument list, I get the parameters presented in bold in the usual Visual Studio way. On thing to note is that the parameters are displayed as a2:Fixnum, that is the class or type is appended to the parameter name in the Delphi style. Personally, I think that this is clearer than the C way where the class name is displayed in front. But it’s easy to change if people want it the other way round. Finally, I can now display the arguments’ IntelliSense. Here you can see a2 really is a Fixnum with the correct tooltip for the Fixnum method chr. Also, note that the method and its full signature is displayed in the drop down combo box at the top left.
Finally, if you think all that is too much to type, just imagine right clicking a method name, selecting Document Block from the menu and getting a nice tabbed snippet with all the arguments filled in ready to complete. All I have to now is write it ...
On a method comment block like this:
#:arg: a1 => String
can you also have a comment for the Intellisense tooltip, maybe something like this
#:arg: a1 => String, The description of the first argument
I am waiting in anticipation for the release of the developer version of ruby in steel. It looks awesome! Being a daytime C# junkie, means I do value IntelliSense when playing with Ruby and Rails in Vs2k5. Good job guys...