Tuesday, August 31, 2010

Things I Love About IntelliJ IDEA: The Impossible is Possible

The features I've written about so far are the ones that I use really often and that I find make the biggest difference for me when I use IntelliJ IDEA. Some of them are a bit mundane, but when I have to code without them I often get the feeling of being bogged down in typing boilerplate.

But there is another side to IntelliJ - an exciting side! IDEA has a whole host of features which, to me, are bordering on mind-blowing. There are quite a few features in IDEA that are so impressive that I don't just think, "That's a clever idea. I'm glad they put that in." What I really think is, "How the hell did they even IMAGINE that that was POSSIBLE?!" Seriously, the Jetbrains guys have implemented tools that I would have laughed at if they were proposed to me, just from the sheer audacity of the ideas and the complexity that I imagine would be involved in implementing them.

One domain where they have been impressing me lately is in their Hibernate integration. If you tell IDEA about a datasource that your Hibernate entities should be able to map to, it can do some cool things like tell you that no table exists with the same name as your entity, or that the column name in your @Column annotation doesn't match any column in the database table. There's also the HQL console, where you can run HQL queries against your database, complete with code-completion from your domain model. Both of these are "Cool, that's useful" features, but I imagine your mouth is not yet agape.

Then they go to the next level: the same code completion that's available in the HQL editor is also available write in the middle of your code using language injection. That's right, those Strings in your Repository classes are no longer just Strings - that first double quote now denotes the point at which Java stops and HQL starts, and IDEA will give you all the help you need to write a query that is correct both syntactically and in respect of your domain model, with name completion, underlining of errors and meaningful error messages. (To enable HQL editing in a class just hit Alt-Enter, select 'Inject Language', then 'HQL')

But after the Jetbrains guys implemented that awesome integration, they got bored, so they had to think of something even more amazing to integrate. Now I see that in the upcoming IntelliJ IDEA X, they have added similar integration to queries created using Hibernate's Criteria API. The ingenuity involved in this feature astounds me - IDEA is observing the annotations on Hibernate entities, parsing Java code and recognising a Criteria query, then building enough understanding of that query and linking it in with the knowledge from the entity classes to be able to make suggestions about the possible and legal properties and relationships that could be queried. It's another example of IDEA being so intelligent that it probably knows more about my code than I do, and the guys have probably re-written half of Hibernate in order to give it to us.

As I said, this is just one domain (no pun intended) that has been impressing me lately. IntelliJ IDEA is full of little nuggets likes this where the Jetbrains developers have dreamed up and then delivered features that are useful so far beyond any little improvements or tweaks that I could have requested as a day-to-day user. This isn't the product of a team of developers tirelessly implementing feature requests from users - it's the constantly evolving creation of a group of highly visionary people who intimately understand the day to day tasks of a coder but are also able to rise above the detail and imagine a better future where the tools don't just help out with the boilerplate but also start to take on some of the heavy lifting.

Tuesday, August 24, 2010

Things I Love About IntelliJ IDEA: Smart Intentional Programming Support

Intentional Programming or "Coding by Intention" is a style of code authoring where, rather than creating low-level parts of code (the building blocks) and then writing the higher-level code (the orchestrators) to bring it together afterwards, you start by writing the high-level code, referencing methods and data that don't yet exist, building up a complete view of the big picture, and then implement the lower-level functions needed to make the big picture work. The main benefit, as you can probably see from my description, is that you get the big picture right and then shape the details to fit, rather than getting the details "right" and then making the big picture fit. **

IntelliJ IDEA has always had great support for coding by intention. It was one of the first 'wow' moments I had when I started using it in the early 00s. Some people have probably never coded without automatic importing, but for those of us who had, the pop-up question "Do you want to import java.util.Properties?" was like black magic. The ability to create a method based on a sample invocation was also in IntelliJ from the very early on, and it was quite revolutionary at the time.

What I love about IntelliJ's intentions is that they really do make the product seem intelligent. You get the impression that the IDE knows just as much about your code as you do, perhaps even more. A great example of this is if you use intentional programming to put() an entry into a non-existent Map and then use IDEA's 'Create Field' intention to create the map.



IDEA guesses (based on the fact that you are invoking a method called put() with two arguments) that maybe the field you want to create is a Map, so it makes that its first suggestion. But it also goes the extra step of suggesting type arguments for the K and V parameters on the Map interface that match the argument types in your intentional code, so that the whole type declaration will be complete simply by your pressing Enter.



Seeing as I've described how IDEA figures this out, it doesn't seem all that magical, but it's actually really useful. IDEA saves you from having to type nearly anything about the new field except perhaps to initialise it with a suitable Map implementation, which is actually just as easy as typing "new " and then hitting Ctrl-Shift-Space.

So, what if you try the same trick with Eclipse?
Eclipse has intentions, but compared to IDEA they're kind of brain-dead…



So Eclipse will make you a field with the right name, but it just declares it with a type of Object. So you have to go up the top and type in the type that you actually want to use, including the type parameters for a Map, yourself. Is that really intentional programming, or does it just save you from copy-pasting the field name?

Another example of IDEA's type-aware goodness can be seen by comparing the expansion of IDEA's "iter" template with Eclipse's "fore" template. Both produce the same Java 5 for-each loop, but IDEA's combination of type-aware template completion and smart name suggesting results in far less typing than the corresponding Eclipse template.

The JetBrains guys are so mad about intentional programming that they've dedicated a whole page of their documentation to showing of their many "intentions".

** If you want to, you can read more about coding by intention here

Monday, August 16, 2010

Things I Love About IntelliJ IDEA: Keyboard Navigation of Search Results

One of the things that really helps IntelliJ IDEA deliver on its claim of increased productivity is the JetBrains guys' fixation with keyboard navigation and one area where they've hit a home run with this is in navigating search results. The idea is actually really simple: you can navigate search results using the keyboard: Ctrl-Alt-Down to go to the next result, Ctrl-Alt-Up to go to the previous one.

If I were just to end the blog there, I'd probably have a throng of Eclipse users banging on my door telling me you can do the same thing in Eclipse: "Just click in the Search View, then use Ctrl+. and Ctrl+," they'd say, and they'd be right. But it's the "Just click in the Search View" part which is all wrong. I shouldn't have to click anywhere. Someone might point out that I can can change the focus between different Views using Ctrl-F7, which again would be correct and would again miss the point.

The point is: I'm coding. I'm writing code; I'm searching code; I'm changing code. I don't want to focus on a Seach View, I want to focus on my code. In IntelliJ, I don't even have to have the Search pane visible to be able to browse through the results. I just have to hit Ctrl-Alt-Down and I'm at the next result, ready to edit. In Eclipse, if the window focus is in the Editor and I want to go to the next Search result, I either have to use the mouse to select and double-click on the next result, or I have to change to the Search View (Ctrl-F7, including pop-up View selector window), press down to select the next result, then press Enter to return to the Editor.

This is one of those niggles in Eclipse about which I like to say, "The guy who wrote the Editor plug-in didn't talk to the guy who wrote the Search plug-in". I often get the feeling that while IDEA is the product of a close-knit team aiming to produce a seamlessly integrated code-authoring masterpiece, Eclipse is just a bunch of code-related tools that have been slapped inside the same GUI without enough thought as to how those tools should play well together.

Monday, August 9, 2010

Things I Love About IntelliJ IDEA: Fast Line Copy & Cut

One of the most common things I do when coding is to copy or cut a single line. The JetBrains guys, having realised this, have made it really easy to do: If you have nothing selected in IntelliJ IDEA and you press Ctrl-C or Ctrl-X, it will copy or cut the current line (respectively, not randomly!). In Eclipse, to copy or cut a line you first have to make the sequence of keystrokes to select the line (Home, Home, Shift-Down) and then copy it with Ctrl-C or cut it with Ctrl-X.

It may not seem like a big difference, but once you've enjoyed the convenience of not having to select a line before copying it, moving back to the select-then-execute method is like moving from a ballpoint pen back to a quill & ink. The difference is simple, but the cumulative effect is lots of time saved. (Look after the pennies.)

Thursday, August 5, 2010

Things I Love About IntelliJ IDEA: Buffer History

With IntelliJ IDEA's Buffer History or "Paste From History" (Ctrl-Shift-V), you can copy multiple snippets and have all of them available for pasting later on. There's no special trick to copy things into the Buffer History - everything copied goes in there. To paste something from the History rather than the lastest copied snippet, just press Ctrl-Shift-V to see the list of available snippets. It's great for a couple of different uses.

Firstly, there are those situations where you need to copy multiple snippets from one source and paste each snippet one or more times at some other destination. For example, you might need to copy multiple sections from one file to another file, which would normally require you to copy one section then paste it in the destination, then come back to copy the other section then paste that into the destination. Or you might be building up a unit test and you have to add two separated lines to each test case, which you would normally do by traversing all the tests once to paste the first line and a second time for the second one.

With the Buffer History, you can just copy each of the sections from the source one after the other, then traverse to the destination and paste each section where it should go. No more jumping back and forth between files, and no more need to traverse the one file multiple times to paste different snippets.

Secondly, the Buffer History helps out in a couple of facepalm scenarios that I often encounter and with which I hope you'll sympathise:
#1: "Urr... I need to paste that thing that I pasted in that other file ten minutes ago. What was that file called again?"
#2 "Aw crap. I just hit Ctrl-C instead of Ctrl-V."

If you encounter either of these in IDEA, just hit Ctrl-Shift-V.
Problem solved.
Facepalm prevented.

I recommend increasing the size of the clipboard history to at least 30. (Search for 'clipboard' in IDEA's Settings.) It doesn't cause any problems to have a larger history and having everything you've copied for the last hour still in the clipboard can save quite a bit of searching.

Monday, August 2, 2010

Things I Love About IntelliJ IDEA: Smart Auto-Completion

Have you ever noticed that when you try to autocomplete something in Eclipse, it shows you half of the code in your classpath? It'll show you classes - both in your package and not - methods and fields - regardless of whether their use would create compilation errors - and templates. Autocompletion in IntelliJ IDEA is made much more useful by dividing the 'feature' of Autocompletion into a set of more specific features. One the one hand, you need to learn a couple of extra key combinations. The advantage, though, is that more specific autocompletion means less options, which means quicker selection. In fact, in many cases, there will only be one valid option, and when this happens IDEA will just complete without popping anything up. (I think Eclipse might do this too, but its "autocomplete as anything" philosophy makes it more rare that there is only one option.)

Here's the different completion options in IDEA and when you should use them:

Ctrl-Shift-Space: Smart (Type-Aware) Completion
This is probably my favourite feature of IntelliJ IDEA. Whenever you are auto-completing at a location that has an expected type - for instance, on the RHS of an assignment or inside the parentheses of a method invocation - type-aware completion will greatly reduce the number of options that appear because it only displays expressions (variables, fields or methods) that match the expected type. This is the key combo that most often feels like magic to me. Sometimes I can just hit Ctrl-Shift-Space four or five times in a row and watch the code that was in my head appear on the screen. And the JetBrains guys are continuing to make this do even more magic: See 'Chained Java Code Completion' and 'Super Completion' at http://www.jetbrains.com/idea/features/code_assistance.html

Ctrl-Alt-Space: Out-of-Scope Class Name Completion
It's actually fairly rare that you'll want to import a new class or interface into a Java source file. Most of the time you auto-complete a class name, it's already in scope, either because it's in the same package, you've already imported it, or its in java.lang. That makes it a bit of overkill to show a list of every class in your classpath every time you try to autocomplete. So Ctrl-Space doesn't do that. But you do obviously need to bring in out of scope classes every now and then, so if you want to complete a class that you haven't already used, hit Ctrl-Alt-Space to see all matching class names. The rest of the time, just use Ctrl-Space to see the classes that you're already using. IntelliJ (like Eclipse) also supports initialised completion. So if you want to use the IllegalArgumentException class, type 'IAE' and hit Ctrl-Alt-Space to see a list of all classes whose first three capitalised words being with 'I', 'A' and 'E'.

Tab: Template Completion
If you know the short name for your template, e.g. "iter", just type it, then tab, voila. If you need to browse for a template, or you only know the first letter or two of the template (e.g. "it"), type what you know and hit Ctrl-J (on Windows and Linux, Command-J on Mac) to see a list of options.

Ctrl-Space: Everything Else
This is the one you use for everything else:
* class names that are already in scope
* methods or fields that don't match the expected type
* completing names when there is no expected type (e.g. invoking a void method)
* completing the declaration of names for variables, fields or parameters

It might seem daunting at first to have four autocomplete options rather than one. However, by giving the IDE a small hint about what kind of thing you're trying to complete, and with the IDE being a bit smarter in assessing what kinds of things might possibly compile if they were completed, the list of options that you are shown is shorter and less confusing than chucking everything in one jolly big list.

Below are screenshots of the different options you will get if you press Ctrl-Space in both Eclipse and IntelliJ IDEA for the same piece of code. Aside from the fact that Eclipse suggested every class beginning with 'B', note that IDEA doesn't suggest blogEntry, boolean or byte, because it knows these wouldn't compile. The really good news is that, if you hit Ctrl-Shift-Space in IDEA here instead of Ctrl-Space, it will just insert blogRoot; complete with semi-colon. Actually, Ctrl-Shift-Space would insert this code even without typing the 'b'.