Saturday, April 21, 2007

Saturday Morning Hack

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


I've heard from a number of people that the ability to jump to a file by type (Open Type), or by filename (Open File) are really important to them. To the point of being adoption blockers.



Both are in the works.



NetBeans has always had a Go To Type for Java (Alt/Ctrl-Shift-O), which we're now retrofitting to become a generic Goto Type facility that other languages can plug into. That means introducing a new API etc. which requires some more effort - so this isn't there for Milestone 9.
However, in the meantime, I've taken the early work on that and hacked it into a Ruby-only module which will let you jump to Ruby types. It's there in the editor context menu (under Go To), bound to a different shortcut. Unlike the general Open Type which will work from any file (or even when you're in a non-source editor window), this will only work from Ruby files. You can get the module
here. That's an NBM file - a netbeans module bundle - which you can install via Tools | Plugins - just switch to the Downloaded tab and point to your NBM. Click Add Plugins. (Sorry, the modules are not signed so you'll get a warning.) It will require a restart. Also, the revamped Plugin Manager is brand new and is stabilizing right now - you may run into some issues. One thing to try is to install one module at a time. You need brand new Ruby bits for this too - go to nbextras.org.



Here's a screenshot of what it looks like (although this includes Java type matches, which the provided hacked module won't do) :






The ability to jump to any file based only on the filename (not the path) is tracked in
issue 44586, and there's been some work happening in a branch. Even though it's not done, you may find it useful in your day to day work. To get it, you can download the module here. Once done, you'll have a Goto File In Project item in your Navigate menu. The operation is faster after the first time.



Finally, I've updated the TextMate snippet importer I recently discussed with some bug fixes - get the latest version here.


Friday, April 20, 2007

Upcoming Gigs

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


It's been a busy month, and it's only going to get busier. Here are some public speaking events that are coming up - I hope you can make it to some of them:


  • I will be speaking at the SD Forum Ruby Conference this weekend, at the San Jose tech museum, with JRuby developer Nick Sieger

  • I have a technical session coming up at JavaOne, TS-9972, along with Martin Krauskopf who is developing the Ruby debugger for NetBeans. It's Thursday afternoon the week of JavaOne.

  • I will also be speaking at NetBeans Day in a Ruby session along with
    JRuby developers Tom Enebo and Charlie Nutter

  • The JavaPosse also has several appearances - there's our BOF Tuesday night at 10pm, we'll be the "lunch entertainment" at NetBeans Day, and we're also planning to do a live episode the following week at the Silicon Valley JUG.

  • Finally, I was recently interviewed on the SDN channel regarding the NetBeans Ruby support. You can find the episode here (you can also subscribe to the SDN via iTunes, it's a video podcast). My segment is about 16 minutes into it, following sections on NetBeans 6 by Tim Boudreau and a Matisse demo by Roman Strobl.









P.S. Another demo tutorial for the NetBeans Ruby on Rails support was just published - it's here. Along with Roman's demo, these are now shipping as sample applications, so you can download the applications themselves and play with the bits.






Ruby Screenshot of the Week #10: Taking Up The Gauntlet

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


SapphireSteel, makers of the Ruby In Steel plugin for Microsoft Visual Studio, has been touting their own code completion feature for a while. One thing which has irked me a bit is that they tend to dismiss "code completion" as inferior to "true IntelliSense" - as if code completion is the name for simple identifier matching. Just to be clear - IntelliSense is a trademark of Microsoft, so nobody else calls the same feature that. Borland has referred to it as CodeInsight, but most IDEs refer to this feature as code completion.



In this article, SapphireSteel is throwing down the gauntlet by encouraging their users to see if anyone else can produce results like theirs:


To the best of our knowledge, Ruby In Steel’s IntelliSense for Ruby is unrivalled by any other IDE. {...}
We’ve also supplied a few files from our IntelliSense test suite which we invite you to use with Ruby In Steel and any other editor or IDE of your choice.



So, I thought I would show what code completion in NetBeans is capable of. Let's start with test 1, which calls for code completion on an array literal in the source:






As you can see, we show the type of methods right in the code completion dialog. It doesn't matter much for an Array, but if you had invoked code completion on the numbers themselves, you'd see that some methods are coming from Integer, and some are coming from its parent class Numeric - and sometimes it's interesting to know that. Next, let's look at
test 2:






The above example shows the type analyzer tracking types of variables.
More interestingly, notice that while we show the methods on the class "above the line", there are other methods there too. Those are methods inherited into MyClass. In the SapphireSteel screenshots, these methods were turned off, presumably because in Visual Studio they would be interleaved with the regular methods. The evaluation document describes how you can turn Object inheritance on and off in the options. I think our solution is nicer because you get the best of both worlds: the methods you are likely most interested in appear first, but when you ned the "standard" methods (they are there for a reason, after all), they also appear. Thus, if you have a String object and you're completing on the letter "e", you see "empty?" (a String method), but also "eval" (an Object method).



Next,
test 3 which tests module mixins:






Looks fine - and so does test 4 which is a more complicated scope test:






Anyway, I don't want to imply that our code completion is perfect! I still have a lot of things I want to do in our type inference engine. In particular, I want to make sure that code completion works well where it really matters: In code you're writing. Here's a final screenshot from a Rails application where you're writing a controller. Code completion works on important methods like render, or a method I found myself calling the other day - send_file:




Rails does a number of things that are very tricky to handle for the IDE, so I'll be spending more time in this area to improve code completion for Rails apps.



P.S. To try it yourself, get bits from nbextras.org. As of yesterday we're in Milestone 9 stabilization, so a promoted build should be available within the next couple of weeks.


Tuesday, April 10, 2007

Ruby Screenshot of the Week #9: Parameter Completion

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Code completion now inserts the parameters for the method you select. They are inserted as a live code template such that you can jump from one parameter to the next using Tab or Return. More importantly, the parameters are also displayed as a tooltip over the method call. You can invoke this whenever you're typing in code - not just using code completion. Hit Alt-P (or on the Mac, Ctrl-P) and if the IDE can figure out the method signature of the method call surrounding the caret, it will display the parameter list, and show the current parameter in bold. As you move the caret around, the tooltip will be updated to show which parameter you're currently editing.






Messing with the user's editing workflow is always risky, so please let me know how you feel the new code completion behavior works. The parameter tooltip depends on being able to figure out the signature of the surrounding method call, which depends on type inference, so it may not always work - but it will also improve as I tweak and improve type analysis across code completion, goto declaration, etc.



Also, there is also a Go To Test action now for jumping quickly between a test class and its unit test. Should work in Rails, RSpec, ZenTest, and also between any classes named Foo, FooTest or TestFoo regardless of which files they're in. This action is in the editor context menu, and is bound to Ctrl-Shift-E. To get this stuff, get at least version 0.65 of the Ruby Feature module (see these installation instructions).



P.S. You can find some more information on the Ruby support in an interview I did with Geertjan Wielenga a couple of weeks ago. There are some other interviews in the same series talking about the new language support in NetBeans. The Rails support in NetBeans will soon have improved support for JavaScript, YAML, and RHTML - stay tuned!


Thursday, April 5, 2007

Ruby Screenshot of the Week #8: Live Code Templates and TextMate Snippets

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


I've received several requests for support for TextMate-style snippets. TextMate is a very popular editor among Ruby developers, and a lot of its power comes from its code snippet functionality. Snippets are basically identical to what NetBeans calls "Live Code Templates". The code templates are live in the sense that when you insert the template, you're in a mode where you can jump from one logical section of the template to another, and edits in one section can automatically be updated in other sections.



I've just implemented an import mechanism for TextMate bundles. Point at your own bundles (or even the ones distributed with TextMate, although I don't know what the legal issues are with that), and choose import.
This will convert all* the snippets into NetBeans Live Code Templates (*=for some values of all).



There are two features in TextMate snippets that are not supported:


  • Command execution. A snippet can contain a `shell command` (in backquotes), and at template evaluation time, the command will be executed and the result inserted. In the snippet bundles I looked at, this was used only for a single thing: inserting parentheses on a conditional basis. So I just made the import handle parentheses directly instead.

  • Regular expression replacement. A template can perform regular expression replacement on different instances of the parameters. I can't even tell exactly how this is supposed to work, but for now, I skip snippets that do this.



TextMate is essentially a text editor; it doesn't (as far as I can tell, having never used it but having read their snippets and macros in detail) have any real semantic information about the code. Therefore, doing complicated text processing with regular expressions is the Way of TextMate to achieve logical code operations. Live Code Templates on the other hand can take advantage of all the information the IDE has about the code.
I've added a bunch of logical code template variables you can use in templates. Rather than try to reproduce the regular expression operations
of TextMate's snippets engine, I would like to create logical Ruby operations for the code templates and use those instead.



Here are some examples of what is possible with this mechanism. None of the imported snippets use these variables, but the imported snippets are useful in their own right - especially for those of you with muscle memory.




${unusedlocal defaults="i,j,k,x,y,foo,bar"}

This will evaluate to an unused local variable in the current scope. It will try to use the provided suggested names, in order. It checks whether each one is already in scope, and if so, tries the next candidate. (If none succeed, it starts appending numbers to find a unique name. If there are more Rubyish ways of generating unique variables, please let me know.)



First, we create the template, naming it "dob":






Then, in some method I want a do-block. I just type "dob" and hit Tab, and voila:






It inserts a do-end block. When it comes to the block variable, it has looked at the context and discovered that the first two preferred alternatives, i and j, are both taken - so it chooses k. This shows the advantage of using semantically aware code templates - you don't accidentally alias an existing variable. This wouldn't be a problem in Java, where it would complain that your new variable already exists in scope, but in Ruby, this is valid (and sometimes, but not usually, what you want.)



As another example, here's a silly template which spits out a hash that defines a bunch of local context:






Let's say I have the following silly file, and type "ctx":






If I now hit tab, I get this:






I will now be able to walk through (with the tab key) each of the variable sections and edit them. For an example like this, it's likely that we don't want these things to be edited by the user - so just add editable=false on each such variable (e.g. ${class editable=false}) and they will be processed but not edited by the user.



One of the things that makes this really powerful, is that it uses a lot of the context information the IDE has about your program. In this example, computing the super class of the current class isn't that hard - and a fancy Ruby shell script executed might be able to pull it off. But if I was simply redefining an existing class, let's say Integer, and there is no local reference to Integer's parent class, the live code template will spit out Numeric. Yes, it looks in the index.


Call for Help



As I've shown, the basic machinery is there now, but what we really need is a set of code templates to be bundled with the IDE. Some will be
simple substitutions or linked variables, but we should be able to come up with some much stronger ones. Please let me know what kinds of
logical parameters you can take advantage of. For example, perhaps a parameter which evaluates to the require statements necessary for
the classes referenced in the file? Or a parameter which looks for database table names in the database? Perhaps some simple transformations which
produce a constant name or a method name (upcasing and downcasing) from some other symbol? There are a lot of possibilities here,
but since I'm not a real Ruby programmer I'm not the best person to dream this stuff up. If you can look at snippets you have written, import them into NetBeans, optionally edit them to add more semantic analysis if appropriate, and contribute them, I'd be very thankful!



Also, I have never used TextMate, so I would appreciate feedback on whether the templates work the way they do in TextMate, or if I misunderstood something from just reading the snippets themselves. Bug reports (preferably via the issue tracker) are much appreciated.



So, where can you get this stuff? I just integrated everything, but the Live Code Template management is not in stock NetBeans; it's in an optional download called "CodeTemplateTools" (in contrib/CodeTemplateTools), written by Sandip Chitale. More info about this module is
here. I have built an NBM you can install directly - just download the module bundle file, then install it via the IDE via the Update Center (in the first panel choose manually downloaded NBM). Note however that you must have the other IDE fixes as well; they should be live on deadlock.nbextras.org soon but probably won't hit the Update Center for a couple of days. (I'll try to make the slim IDE bundle the tools). As always, see the wiki for installation instructions. Once you have installed the Code template tools, look for "Show Templates..." in the Edit menu. The import UI is still a bit rough - no progress bar etc - I'll worry about that later. There's one more rough spot: the "|" character must be escaped (by typing it twice) because historically, NetBeans used "|" to indicate the cursor position. There is the logical variable ${cursor} for that now, but there's still some issues we need to resolve in this area.